Created attachment 18006 [details] fake smb server that returns a bogus level to smbclient -L In smbclient -L, browse_host_rpc() uses info_ctr.ctr.ctr1 if dcerpc_srvsvc_NetShareEnumAll() returns OK: for (i=0; i < info_ctr.ctr.ctr1->count; i++) { ndr_pull_srvsvc_NetShareEnumAll() allocates a heap block which dcerpc_srvsvc_NetShareEnumAll() later copies over info_ctr: if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.info_ctr); } Ordinarily the content of the info_ctr heap block is initialized in one of the arms of the switch statement in ndr_pull_srvsvc_NetShareCtr(). But if the "level" supplied by the server doesn't match any of the switch cases, then the heap block isn't initialized, but ndr_pull_srvsvc_NetShareCtr() still returns OK. As a result, if the server returns a bogus "level", browse_host_rpc() can trip over a garbage info_ctr.ctr.ctr1. I've attached a demo smb server which causes smbclient -L to crash if compiled with a debugging malloc.
The loop in browse_host_rpc() assumes that info_ctr.level is 1 and that the array is non-NULL if count > 0, but dcerpc_srvsvc_NetShareEnumAll() doesn't necessarily conform.