Rpc Spoofing

  • Upload
    sh0nex

  • View
    216

  • Download
    0

Embed Size (px)

Citation preview

  • 8/8/2019 Rpc Spoofing

    1/4

    *****************************************************A White paper on RPC Spoofing and Packet Construction

    by JimJones [zsh] 2000http://zsh.interniq.org

    *****************************************************

    1. Introduction---------------Let me start off by saying that by no means do I claim any sparkof originality in writing this article. RPC spoofing isn't avery novel idea, but what caused me to write this was the factthat it is very rarely implemented. I give smiler credit sincehe has been making his RPC exploits with spoofing capabilitiesfor some time now, notably humpdee2, and he was the cause of myinterest in exploring this. . Now that I've made it clear thatthis isn't anything ground-breaking or revolutionary (justoverlooked), I will continue.

    2. Basic Overview-----------------What is RPC? Well I'm hoping that you at least have a basicunderstanding of remote procedure calls and how they work, sincethis is a more intermediate discussion of them. Let's lay asideTLI and transport-independent mechanisms for a moment, and webasically find RPC implemented over two main protocols: TCP andUDP. This article will only focus on UDP, since that logically

    seems like the best transport layer to attack. Sure, it would bepossible to come up with a TCP-based RPC spoofing tool, butwould this really be worth the effort? Most RPC services listendually on UDP and TCP ports, and those that listen on only oneof the two more than often tend to be UDP-based. Predictingsequence numbers is so cumbersome when compared to merelyforging an IP packet.

    The beauty of the RPC protocol, from a hacker's perspective,isthat it has no inherent integrity measures. Well, user and DESauthentication are both supported in ONC standards, but yourarely see this used. The RPC datagrams don't have checksums or

    signatures or handshake procedures inherently. Simply sendingone packet will get the job done. So now that I'm done with thebasics, It's time to get into the technical details.

    3. Low Level RPC Packet Construction------------------------------------The definitions we are about to look at can also be found byfollowing along in We see the following structure:

    struct rpc_msg {u_int32_t rm_xid;

  • 8/8/2019 Rpc Spoofing

    2/4

    enum msg_type rm_direction;union {

    struct call_body RM_cmb;struct reply_body RM_rmb;

    } ru;

    The RPC message is a static length (except for TCP, where a

    length component is prepended to the packet), and is alwaysgenerally the same.

    The xid is a 32 bit unique message identifier which is used todistinguish between packets and requests on a busy RPC server,like a ticket. The value which you assign to this variable isreally unimportant, because you're not expecting a reply, norwill the non-0 xid be rejected.The direction will always be assigned type CALL for obviousreasons, Remember to always use proper network ordering whencreating your messages. Simply htons () and htonl () calls willdo.

    The RPC message format uses a union to represent either a callor a reply in the same space. The next element of this datastructure is ru.RM_cmb, which we can reference as rm_call,as that's what it's also defined to be.

    Now we take a look at the call body.struct call_body {

    u_int32_t cb_rpcvers; /* must be equal to two */u_int32_t cb_prog;u_int32_t cb_vers;u_int32_t cb_proc;struct opaque_auth cb_cred;

    struct opaque_auth cb_verf; /* protocol specific - provided by client */};

    As the include file suggests (and it's always wise to followtheir suggestions), cb_rpcvers should always be set to 2, asthis is the version of the RPC communications that take place.cb_prog is the 32 bit program number of the RPC service you arecalling, cb_vers is the version of the service, and cb_proc isthe procedure number. The user-defined RPC procedures start with1 and usually move incrementally upwards, since 0 has beenreserved on all ports for a null procedure test.

    Now, the next part that comes here is the authenticationportion. There aren't a whole lot of services that areconfigured for user authentication, so it won't be discussed indetail. But in any case, there are 3 types supported universally:NULL or no authentication, user-based authentication whichpasses the server a user ID, group ID, and a machine name, andDES authentication with encrypted timestamps.Anyhow, null authentication, as the name implies, simplyconsists of null (0) bytes. Oh, another thing. These twovariables are both type "struct opaque_auth." Opaque structuresand data in RPC are basically those which are not analyzed bythe RPC implementation and remain open for examination by theserver and client. This can be likened to a free-form binary

    string.

    For simple reasons, I would not suggest that anybody construct

  • 8/8/2019 Rpc Spoofing

    3/4

    DES-authenticated RPC packets by hand.

    So, that's actually essentially there's all to it for a simplespoofing mechanism. We simply insert the body of the RPC messageafter the header (by the body of the message, I mean theparameters to the RPC function call) and that's what we send tothe server. Now, if you're competent with RPC programming, you

    know how to use XDR (eXternal Data Representation) to formatparameters. Instead of passing your parameters to a functioncreated by rpcgen, for example, you simply concatenate them, oneafter another, and add them on to the end of your RPC message.You don't need to create any other data objects. The remote endwill decode your parameters.Since it is expecting certain parameters, it will only read afixed amount of bytes from the data stream and then cast them tothe appropriate type. Even variable length parameters are eitherNULL-terminated or have length byte(s).

    4. There's a Catch------------------OK. So you've spoofed the RPC packet and ran our exploit?Everything's fine, right? Well, from a naive perspective. Tosend the packet, you of course had to know the remote UDP portthe RPC service was listening on. So you might have ran acommand like rpcinfo to find out the list of services availableand mapped the service to its corresponding port. RPC services,of course, dynamically bind to assigned ports. These portschange constantly; only program numbers remain constant. So each

    time you want to send the packet you have to find out which portit is. When you run rpcinfo on a host prior to exploiting it,you're usually defeating the purpose of RPC spoofing. rpcinforequires a virtual circuit to be used for transport, so you'redivulging your address when you make a request. Even if you dothis via proxy, a logger can detect that the operation tookplace. You could do a NULL UDP scan (ala halflife's suggestedmethod), but this too could trip IDS systems when they identifya potential intruder.

    Luckily, there's a trick to circumvent this.

    We can see the code for this by following along in. rpc.portmap has 5 standard procedures whichare defined (excluding the NULL procedure test). The procedurethat we are interested in is procedure #5.The following lines of code detail it:

    #define PMAPPROC_CALLIT ((u_long)5)PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string)encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs);

    If rpc.portmap listens on UDP port 111 (which it probably does,since only PMAPPROC_DUMP() requires TCP transport), you can usethis procedure to pass your parameters along to the specified

    program, version, and procedure, regardless of whether or notyou know the port. And we always know these parameters whenrunning the exploit.Now we can spoof completely blindly, without

  • 8/8/2019 Rpc Spoofing

    4/4

    ever having to know the port the service runs on.

    Remember the 3 fields we filled in with the program information(cb_prog, cb_vers, cb_proc)? We're calling our service nowindirectly through portmapper. So we take these 3 fields, andpass them to PMAPPROC_CALLIT before we call string. In theirplace, we have the following defines:

    #define PMAPPROG ((u_long)100000)#define PMAPVERS ((u_long)2)#define PMAPPROC_CALLIT ((u_long)5)cb_prog = 100000, cb_vers = 2, and cb_proc = 5

    Just a note: PMAPPROC_CALLIT () will only work for UDP anyhow,so this will fail otherwise.

    Also, try to be creative.If you are spoofing for the purpose of feigning the existence ofa trusted host, and not merely to "stay out of sight," remember

    to tailor your packets well. A locked down box will probablyhave rigid packet-filtering rules in place. For this scenario,it is probably a good idea to set your source UDP port as either 111,or some other well known services such as snmp (161) or dns (53),as ADMFZap did to avoid poorly configured software.

    Good luck, and happy spoofing -)

    Other Materials and References------------------------------Not all of these resources are completely relevant to thesubject of low level RPC programming, but they are certainlyuseful if you wish to do development. I think I remember UNIXNetwork Programming Volume 2 with a section on RPC packets butI'm not quite sure.These are references I have checked outthough.

    Power Programming with RPC by John Bloomerhttp://www.crc-tgr.edu.au/docs/dec/AA-Q0R5B-TET1_html/INDEX.htmlhttp://www.uccs.edu/~compsvcs/doc-cdrom/DOCS/HTML/AQ0R5BTE/DOCU_004.HTM