Date: Wed, 18 Aug 1999 18:29:17 -0300
From: Ivan Arce <[email protected]>
To: [email protected]Subject: Solaris rpcbind tricks
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 I believe it might be worth a post to bugtraq.
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 i didnt have time to
investigate further till last week.
Sebastian R. Wain <[email protected]> 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.
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, i believe 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...
--
"Understanding. A cerebral secretion that enables one having it to know
a house from a horse by the roof on the house,
It's nature and laws have been exhaustively expounded by Locke,
who rode a house, and Kant, who lived in a horse." - Ambrose Bierce
--------------------------------------------------------------------------------------------
IvАn Arce <[email protected]>
Presidente
CORE SDI S.A.
Pte. Juan D. Peron 315 4to UF17 (1394) Buenos Aires, Argentina.
TE/FAX: +54-11-43-31-54-02 +54-11-43-31-54-09
PGP fingerprint: C7A8 ED85 8D7B 9ADC 6836 B25D 207B E78E 2AD1 F65A
--------------------------------------------------------------------------------------------