COMMAND

    rpc.bind

SYSTEMS AFFECTED

    Solaris

PROBLEM

    Ivan Arce posted following.   While this is hardly  a new bug  and
    the  dangers  of  not  having  proper anti-spoofing checks in your
    perimeter router/firewall has been discussed over and over in  the
    past years.   The following can  be taken as  an example of  how a
    combination of bugs, protocol  flaws and bad coding  practices can
    bring  to  life  new  incarnations  of  ancient security problems.
    This was discussed months ago with Oliver Friederichs and Theo  de
    Raadt over considerable  amounts of beer,  since then Ivan  didn't
    have time  to investigate  further till  last week.   Sebastian R.
    Wain  provided  a  lot  of  his  time testing and figuring out the
    detailst.

    Bypassing restrictions for the PMAPPROC_CALLIT procedure in rpcbind
    ===================================================================
    Altho. rpcbind/portmap explicitly restricts which programs can  be
    contacted using  PMAPPROC_CALLIT there  is a  way to  bypass these
    restrictions in Solaris.   Upon startup Solaris'  rpcbind opens  a
    socket  that  will  be  used  to service PMAPPROC_CALLIT requests,
    this  is  refered  as  the  'Non  Standard  Port' in the NAI-0015:
    Solaris rpcbind weaknesses  advisory and Sun's  Security Bulleting
    #142 and  on these  pages is  available too.   The advisory  makes
    clear  that  older  rpcbind  programs  also  allowed  and serviced
    incoming RPC calls on that port.  This is no longer the case,  but
    the port is used to send outgoing RPC calls that correspond to RPC
    PMAPPROC_CALLIT  requests  received  on  the standard rpcbind port
    (111/udp and tcp).

    For that  purpose rpcbind  allocates an  internal table  that maps
    the received CALLIT requests to the requests forwarded by  rpcbind
    to service those requests.   This mapping is done by  matching the
    RPC  XIDs  of  both  the  received  and forwarded calls.  The XIDS
    generated for the  forwarded calls can  be guessed since  they are
    not entirely random.  The source port of the forwarded calls  does
    not vary between different PMAPPROC_CALLIT calls.

    Provided that one can inject  spoofed packets on the network  that
    is running  the RPC  services it  is possible  to communicate with
    ANY RPC service AND obtain  RPC replies using PMAP_CALLIT.   As an
    example, lets describe how one  could still grab file handles  out
    of  mountd  [assuming  that   attacked.host.com  is  exporting   a
    filesystem   and   allows    bouncing.host.com   to   mount    it,
    attacking.host.com is able to mount it following these steps]:

        1. Attacker sends a spoofed   PMAPPROC_SET call to register  a
           service  named  "bogusd"  on  the  any  available  port  on
           localhost.

           src addr : 127.0.0.1
           dst addr : bouncing.host.com
           dst port : 111
           program  : rpcbind
           procedure: PMAPPROC_SET
           data     : BOGUSPROG,BOGUSVERS,BOGUS_PORT,etc

        2. Attacker sends NON-spoofed calls to PMAPPROC_CALLIT  asking
           to call bogusd procedure FOO.

           src addr : attacking.host.com
           dst addr : bouncing.host.com
           dst port : 111
           program  : rpcbind
           procedure: PMAPPROC_CALLIT
           data     : BOGUSPROG,BOGUSVERS,BOGUS_PROCFOO,etc

        3. Attacker sends  a set of  spoofed replies to  the port that
           rpcbind uses for  forwarding of RPC  calls.  Each  reply in
           this set has a different XID choosen from a given range.

           For each spoofed reply:
           src addr : 127.0.0.1
           src port : BOGUS_PORT
           dst addr : bouncing.host.com
           dst port : rpcbind_forwarding_port (usually around 32500 )
           XID      : xid_i ( 0 < i < I ;  xid_0 is calculated using information
                      about the bouncing.host.com's uptime)

        4. Attacker waits for a RPC  reply to one of his CALLIT  calls
           to bogusd, procedure BOGUS_NULL.  The attacker will receive
           a reply when one of the  spoofed replies sent in (3) had  a
           matching  XID.   The  attacker  has  guessed  the  XID that
           rpcbind used (XID_j / i <  j < I) and can predict  the next
           one (we call it XID_j+1)

        5. attacker sends rpcbind  a NON-spoofed CALLIT call to BOGUSPROG

           src addr : attacking.host.com
           dst addr : bouncing.host.com
           program  : rpcbind
           procedure: PMAPPROC_CALLIT
           data     : BOGUSPROG,BOGUSVERS,BOGUS_PROCFOO,etc

        This will  generate a  RPC call  from rpcbind  on the bouncing
        host to BOGUS_PROGRAMNUM on the bouncing host as follows:

           src addr : bouncing.host.com
           src port : rpcbind_forwarding_port
           dst addr : bouncing.host.com
           dst port : BOGUS_PORT
           program  : BOGUSPROG
           procedure: BOGUS_PROCFOO
           XID      : xid_j+1

        6. attacker  sends  a  spoofed  call to mountd's  RPCMNT_MOUNT
           procedure with:

           src addr : bouncing.host.com
           src port : rpcbind_forwarding_port
           dst addr : attacked.host.com
           dst port : MOUNTD_PORT
           program  : MOUNTPROG
           procedure: MOUNT_PROCMNT
           XID      : xid_j+1

        7. mountd on  the attacked host  replies to this  request with
           the proper filehandle, rpcbind will get the reply, match it
           to  a  previous  CALLIT  request,  and  pass it back to the
           caller.

           The attacker has just  grabbed a filehandle, bypassing  the
           restrictions imposed in rpcbind for CALLIT calls.

           Its important to notice that altho the attacker is spoofing
           she  does  receive  the  responses  from  the service being
           attacked, this is  done by the  kind vulnerable rpcbind  on
           the bouncing host.

    This is possible because:

        1. XIDs of the forwarded calls are predictable
           Assuming that our RPC calls to rpcbind, PROC_CALLIT are the
           first CALLIT requests received  by the bouncing host  since
           it was booted (this is  a fair assumption) and knowning  or
           being able to aproximate.   The uptime of the target  host,
           the  XIDs  that  rpcbind  will  generate  for the forwarded
           requests can be easily predicted.

        2. Theres no check for the src address and port of the replies
           to forwarded calls to match the dst address and port of the
           original  call.   rpcbind  does  not  check  that RPC reply
           messages, received  on the  socket used  to forward  CALLIT
           requests,  have  a  valid  source  address,  port, prognum,
           progvers, etc.

    Given this, the exploit can be used to 'bounce' mount requests off
    any  Solaris  host  allowed  to  mount  a NFS file system local or
    remote.   However, in  order to  succeed, the  target mountd  must
    allow mount requests from  unpriviledged ports.  This  same scheme
    can be used to comunicate with any RPC service.

    Altho. no exploit  code is provided,  it is believed  the detailed
    explanation of  the steps  to follow  is more  than enough to code
    your own testing program.

    Keep  in  mind  that  this  arises  from  several  trivialy  fixed
    problems:

        . DO NOT allow spoofed packets into your network
        . allowing connections to  rpcbind from external addresses  is
          not a good idea.
        . mount requests from unpriviledged ports are not a good idea
        . Exposing  server information  that by  itself can  be deemed
          inocuos can help attackers  in their efforts, in  this case,
          exposing the  uptime of  your Solaris  box is...  not a good
          idea..  who would have thought eh?

    As for localnet...  well, no one  has to go  thru all this  if you
    have access to the local net and can sniff and spoof NFS packets..

SOLUTION

    These attacks only work on unpatched Solaris 2.6 and before.   The
    relevant Sun bug is:

        4070261 predictable RPC XIDs when forwarding CALLIT RPCs

    The following patches  that have been  around for quite  some time
    fix this problem:

        102034-05: SunOS 5.3: usr/sbin/rpcbind patch
        102070-06: SunOS 5.4: usr/sbin/rpcbind patch
        102071-06: SunOS 5.4_x86: usr/sbin/rpcbind patch
        104331-07: SunOS 5.5.1: /usr/sbin/rpcbind patch
        104332-07: SunOS 5.5.1_x86: /usr/sbin/rpcbind patch
        104357-06: SunOS 5.5: usr/sbin/rpcbind patch
        104358-05: SunOS 5.5_x86: usr/sbin/rpcbind patch
        105216-03: SunOS 5.6: /usr/sbin/rpcbind patch
        105217-03: SunOS 5.6_x86: /usr/sbin/rpcbind patch

    Solaris 7 has this bug fixed.