Skip to content

fuzzrf/openbsd_ov1

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 

Repository files navigation

OpenBSD TCP/IP overflow

Tested with latest OpenBSD 7.2

Details:

int
ip_dooptions(struct mbuf *m, struct ifnet *ifp)
{
	...
  for (; cnt > 0; cnt -= optlen, cp += optlen) {
                opt = cp[IPOPT_OPTVAL];
                if (opt == IPOPT_EOL)
                        break;
                if (opt == IPOPT_NOP)
                        optlen = 1;
                else {
                        if (cnt < IPOPT_OLEN + sizeof(*cp)) {
                                code = &cp[IPOPT_OLEN] - (u_char *)ip;
                                goto bad;
                        }
                        optlen = cp[IPOPT_OLEN];
[1]                     if (optlen < IPOPT_OLEN + sizeof(*cp) || optlen > cnt) {
                                code = &cp[IPOPT_OLEN] - (u_char *)ip;
                                goto bad;
                        }
                }

                switch (opt) {

				  case IPOPT_LSRR:
                  case IPOPT_SSRR:
                        if (!ip_dosourceroute) {
                                type = ICMP_UNREACH;
                                code = ICMP_UNREACH_SRCFAIL;
                                goto bad;
                        }
                        if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
                                code = &cp[IPOPT_OFFSET] - (u_char *)ip;
                                goto bad;
                        }
 						...
						...	
						off--;                 
                        if ((off + sizeof(struct in_addr)) > optlen) {
                                save_rte(m, cp, ip->ip_src);
                                break;
                        }


	...
}

void
save_rte(struct mbuf *m, u_char *option, struct in_addr dst)
{
        struct ip_srcrt *isr;
        struct m_tag *mtag;
        unsigned olen;

        olen = option[IPOPT_OLEN];
        if (olen > sizeof(isr->isr_hdr) + sizeof(isr->isr_routes))
                return;

        mtag = m_tag_get(PACKET_TAG_SRCROUTE, sizeof(*isr), M_NOWAIT);
        if (mtag == NULL) {
                ipstat_inc(ips_idropped);
                return;
        }
        isr = (struct ip_srcrt *)(mtag + 1);

        memcpy(isr->isr_hdr, option, olen);
[2]     isr->isr_nhops = (olen - IPOPT_OFFSET - 1) / sizeof(struct in_addr);
        isr->isr_dst = dst;
        m_tag_prepend(m, mtag);
}



struct mbuf *
ip_srcroute(struct mbuf *m0)
{
        struct in_addr *p, *q;
        struct mbuf *m;
        struct ip_srcrt *isr;
        struct m_tag *mtag;

        if (!ip_dosourceroute)
                return (NULL);
		...
[3]		p = &(isr->isr_routes[isr->isr_nhops - 1]);
        *(mtod(m, struct in_addr *)) = *p--;

        /*
         * Copy option fields and padding (nop) to mbuf.
         */
        isr->isr_nop = IPOPT_NOP;
        isr->isr_hdr[IPOPT_OFFSET] = IPOPT_MINOFF;
        memcpy(mtod(m, caddr_t) + sizeof(struct in_addr), &isr->isr_nop,
            OPTSIZ);
        q = (struct in_addr *)(mtod(m, caddr_t) +
            sizeof(struct in_addr) + OPTSIZ);
#undef OPTSIZ
        /*
         * Record return path as an IP source route,
         * reversing the path (pointers are now aligned).
         */
[4]     while (p >= isr->isr_routes) {
                *q++ = *p--;
        }
	...
}

1. on line #1 - we can set optlen == 2
2. save_rte() will set isr_nhops to very large value, 
because (optlen - IPOPT_OFFSET - 1) equals to 0xffffffff (IPOPT_OFFSET=2)

3. ip_srcroute() call will trigger buffer overflow on loop #4

Preconditions:

1. source routing should be enabled for this to work.
2. we disable PF as it discards such packets

How to reproduce:

1. install OpenBSD
2. add the following line to /etc/sysctl.conf
net.inet.ip.sourceroute=1

3. run syspatch to install latest patches
4. reboot the system
5. disable pf
# pfctl -d

2. run proof of concept

Fix https://github.com/openbsd/src/commit/d49c6b9957f582865e3b14a12dc9021e40852a81

About

OpenBSD remote overflow

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published