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 <swain@core-sdi.com> 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 <ivan@core-sdi.com> 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 --------------------------------------------------------------------------------------------
This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:57:12 PDT