Nmap Development mailing list archives
Status Report #8 of 15
From: Dražen Popović <drazen.popovic () fer hr>
Date: Tue, 22 Jun 2010 03:37:18 +0200
Hi everyone. I started working on "ndr.lua", an Lua library that will be used for handling NDR packing and unpacking [1]. This is a very important library as it represents the very basis for MSRPC protocol. Till now "msrpctypes.lua" was used for the same purpose, but I came across many irregularities and design flaws which convinced me to make "ndr.lua". So far things are going great, mostly to my newly developed MIDL_BENCH testing environment which saves me a lot of trouble and time. So... Accomplishments: * "ndr.lua" has a working code that packs all of the NDR primitive types (boolean, small, short, long, octet, char, enum) and all of the NDR unidimensional arrays (conformant, varying and conformant-varying). These have been tested against DRAZEN_SVC custom built RPC service used for testing purposes (within MIDL_BENCH). Test cases were developed so that they target the most tricky alignment issues...and so far "ndr.lua" passes smoothly. * DRAZEN_SVC MSRPC service is a project within MIDL_BENCH VS solution used for testing NDR packing and unpacking as well as IDL to NDR mapping. This project contains the IDL definition of the service interface, the server code and the client code which can be used to resolve any NDR packing issues (shark sniff). So far it contains 7 RPC procedures which are used for testing "ndr.lua" NDR packing correctness. * "cli-drazen-svc.nse" is a NSE script which represents the RPC client to the DRAZEN_SVC interface. There you can find the actual client side methods that pack the NDR and calls the server side RPC procedure. It's used for testing "ndr.lua". * Started working on NDR structure packing which lead to the drastic design changes. This is the most complex NDR type and thus it must be implemented elegantly and clean to avoid future problems. So far I have a design draft, new classes and such. Priorities: * Finish the NDR structure type packing and begin the first test/debug iteration. When this is done, the rest of NDR types packing will follow shortly because the hard part is over. * Make NDR packing methods for top-level and embedded pointers (full, unique and referent), unions, strings and multidimensional arrays. * When done with packing, get to unpacking which should go rather smoothly as the concept is similar (if not the same). * Test the "ndr.lua" on a real service...this is where all the fun begins where I will make the "epmapper.nse" [2] script which lists all of the Endpoint Mapper registered services (for you not familiar with MSRPC Endpoint Mapper that's the TCP port 135) and is in a way similar to portmapper NSE script. * Once we have a stable "ndr.lua" the time is wright for LIDL to come. :) LIDL is a IDL parser that will use PIDL to do most of the hard work and thus we will generate clients for various RPC services automatically providing just the IDL definition of the RPC interface (similar to rpcgen used in SUN RPC). Notes: To validate my motivation for making "ndr.lua" let me show everyone the code I used to prove flaws in "msrpctypes.lua" code. For the testing purposes I made an RPC procedure called TestPrimTypesPacking1 in DRAZEN_SVC. This is the IDL definition of this procedure: --################################## void TestPrimTypesPacking1( [in] small _small, [in] unsigned small _usmall, [in] short _short, [in] unsigned short _ushort, [in] long _long, [in] unsigned long _ulong, [in] hyper _hyper, [in] unsigned hyper _uhyper, [in] boolean _bool, [in] char _char, [in] byte _byte ); --################################## To call with the above procedure I made two client stubs DRAZEN_SVC_TestPrimTypesPacking1 and DRAZEN_SVC_TestPrimTypesPacking1_msrpctypes. A short code snippet for both of them: --################################## function DRAZEN_SVC_TestPrimTypesPacking1(smbstate, sm, usm, sh, ush, l, ul, h, uh, bo, c, by) --sanity check --pack the request local tptp1_ndr; tptp1_ndr = NDR:new() tptp1_ndr:push_small(sm) tptp1_ndr:push_small(usm) tptp1_ndr:push_short(sh) tptp1_ndr:push_short(ush) tptp1_ndr:push_long(l) tptp1_ndr:push_long(ul) tptp1_ndr:push_hyper(h) tptp1_ndr:push_hyper(uh) tptp1_ndr:push_bool(bo) tptp1_ndr:push_char(c) tptp1_ndr:push_octet(by) --call the function ... --################################## and --################################## function DRAZEN_SVC_TestPrimTypesPacking1_msrpctypes(smbstate, sm, usm, sh, ush, l, ul, h, uh, bo, c, by) --sanity check --pack the request local tptp1_req_blob; tptp1_req_blob = msrpctypes.marshall_int8(sm) tptp1_req_blob = tptp1_req_blob .. msrpctypes.marshall_int8(usm) tptp1_req_blob = tptp1_req_blob .. msrpctypes.marshall_int16(sh) tptp1_req_blob = tptp1_req_blob .. msrpctypes.marshall_int16(ush) tptp1_req_blob = tptp1_req_blob .. msrpctypes.marshall_int32(l) tptp1_req_blob = tptp1_req_blob .. msrpctypes.marshall_int32(ul) tptp1_req_blob = tptp1_req_blob .. msrpctypes.marshall_int64(h) tptp1_req_blob = tptp1_req_blob .. msrpctypes.marshall_int64(uh) local bo_val if(bo == true) then bo_val = 1 else bo_val = 0 end tptp1_req_blob = tptp1_req_blob .. msrpctypes.marshall_int8(bo_val) tptp1_req_blob = tptp1_req_blob .. msrpctypes.marshall_int8(c) tptp1_req_blob = tptp1_req_blob .. msrpctypes.marshall_int8(by) --call the function ... --################################## As you can see the difference between them is that the first uses "ndr.lua" packing methods, and the other uses "msrpctypes.lua". The later resulted with incorrect NDR unpacking on the server side, which was expected as it does not handle the alignment correctly. These are only the issues concerning the primitive types, unfortunately more follow . :( As I stated before NDR is the MSRPC base, and till now I looked at few implementations of NDR ("msrpctypes.lua", PyMSRPC, Ruby REX:Ndr and SAMBA). And it seems that only SAMBA guys did the job correctly, but not too elegantly. The reason for that is that no one seems to have realized that the NDR is context dependent as far as the alignment calculations are concerned and that pointers have a scope inside which they must obey certain rules. When in debugging nightmare I turn to MIDL_BENCH, also I use the --ndr-parser output of the PIDL parser and I use the WShark sniff of the MIDL generated client only to find out that it's all there in The Book [4], but sometimes too hard to read. :) Cheers, Dražen. [1] http://en.wikipedia.org/wiki/Network_Data_Representation [2] http://www.cultdeadcow.com/tools/rpcdump.html [3] http://wiki.wireshark.org/Pidl [4] http://www.opengroup.org/onlinepubs/9629399/toc.htm -- Laboratory for Systems and Signals Department of Electronic Systems and Information Processing Faculty of Electrical Engineering and Computing University of Zagreb _______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://seclists.org/nmap-dev/
Current thread:
- status report #8 of 15 kirubakaran S (Jun 21)
- Re: status report #8 of 15 David Fifield (Jun 22)
- <Possible follow-ups>
- Status Report #8 of 15 ithilgore (Jun 21)
- Status Report #8 of 15 Luis MartinGarcia. (Jun 21)
- Status Report #8 of 15 Dražen Popović (Jun 21)
- Re: Status Report #8 of 15 David Fifield (Jun 22)
- Re: Status Report #8 of 15 Dražen Popović (Jun 23)
- DRAZEN_SVC testing David Fifield (Jun 24)
- Re: DRAZEN_SVC testing Dražen Popović (Jun 24)
- Re: Status Report #8 of 15 David Fifield (Jun 22)