cddmp / enum4linux-ng

A next generation version of enum4linux (a Windows/Samba enumeration tool) with additional features like JSON/YAML export. Aimed for security professionals and CTF players.
GNU General Public License v3.0
1.18k stars 125 forks source link

Add options to customize service ports #24

Closed fourcube closed 2 years ago

fourcube commented 2 years ago

Thanks for your work on this great tool!

Currently all ports are hardcoded via the SERVICES dictionary. It would great to set the ports via command line arguments.

SERVICES = {
        SERVICE_LDAP: 389,
        SERVICE_LDAPS: 636,
        SERVICE_SMB: 445,
        SERVICE_SMB_NETBIOS: 139
}

I would propose the following flags to set the ports.

--ldap-port 389
--ldaps-port 636
--smb-port 445

I'd be happy to contribute a PR to this.

cddmp commented 2 years ago

Hi fourcube,

thanks for your request! I had actually started implementing that months ago, but I remember that I came across an issue. From what I remember, it was not possible with all Samba tools to pass in an arbitrary port also passing them in via a special smb.conf file did not work. Since this also can be done with iptables/nft redirects I dropped that idea.

So I just checked that again, at least version 4.13.14-Debian, as shipped with Kali, seems to support a "-p" parameter now. Maybe the best way forward would be to test that parameter works as expected? Apart from that the flags look good to me! One possible problem could be, that at the moment the Samba client tools try the ports 139 and 445 automatically. If you now want to change both ports, e.g. 139 --> 1139 and 445 --> 1445 the tool needs to run all enumeration steps twice.

fourcube commented 2 years ago

Hi, thank you for taking a look at this so quickly.

Since it's not possible to customize the two ports that smbclient uses, it could make sense to just use a single flag.

I will check and see how smbclient behaves when some custom port is specified, I will probably have to dig through the source a little. I wasn't able to determine how smbclient / rpcclient decide on the protocol to use when the port is given via a command line argument.

cddmp commented 2 years ago

Thank you! For any changes, please use the dev branch. I have some major code changes in there.

cddmp commented 2 years ago

I did some quick testing with socat and smbclient. When you use port 139/tcp, smbclient will try to setup a NetBIOS session, as expected. For 445/tcp it tries to negotiate the SMB dialect, also as expected. Now when I use socat and forward 12345/tcp to my target machine on port 139/tcp, smbclient will still try to negotiate the SMB dialect. This fails, because a NetBIOS session initiation is expected on port 139/tcp. smbclient won't try to fallback to NetBIOS. If I instead forward from 12345/tcp to 445/tcp the dialect negotatiation will work.

In other words: I think smbclient will only use NetBIOS if you use port 139/tcp, for all other ports it will skip NetBIOS. Therefore, whatever you specify with -p won't do a NetBIOS session. So we can change the port for 445/tcp but not for 139/tcp. I still might be wrong.

fourcube commented 2 years ago

That's what I found out too. After unsuccessfully digging through the code samba 4 source code, I reached out to #samba and #samba-technical to see if anyone has an idea if it's possible to either

a) choose the protocol independent of the port b) overwrite the smb ports with two alternate ports

I haven't gotten an answer yet, I'll keep digging for a little while longer.

I was thinking about about maybe replacing the smbclient invocation with something else, like impacket smbclient.py. What would be your stance on that?

cddmp commented 2 years ago

I also found this: https://github.com/samba-team/samba/blob/e742661bd2507d39dfa47e40531dc1dca636cbbe/source3/libsmb/smbsock_connect.c#L378-L405 This looks to me, as if a NetBIOS session setup is really only done when port == 139. If there is no other path in the code, then it does not seem to be possible to choose the protocol independent of the port.

I had planned to replace the Samba tools on a wider scale with impacket, but then I realized, that impacket does not fully support SMB3, e.g. the most recent dialect 3.11 is not fully supported by impacket. Because of that, we need to stick with the Samba tools at the moment.

fourcube commented 2 years ago

That code appears to be located inside the source3 tree. Is this still used for the 4.x cli?

Inside the source4 tree I found this code to handle the connection:

https://github.com/samba-team/samba/blob/e742661bd2507d39dfa47e40531dc1dca636cbbe/source4/client/client.c#L3499

It appears to grab the ports via a call to lpcfg_smb_ports. That function is generated during the build somehow (https://github.com/samba-team/samba/blob/master/lib/param/README) and I wasn't able to take a look at it's source code.

I tried to pass the value of "smb ports" via the --option="smb ports"="11445 11139" flag but the -d 10 output still showed that smbclient tried to connect to the original ports (445 139).

cddmp commented 2 years ago

This post had indicated to me, that they merge things somehow, but I only had a quick look. https://lists.samba.org/archive/samba/2016-July/201182.html

fourcube commented 2 years ago

Thank you again for taking the time to look at this again.

So it seems as if this is still not easily solvable with smbclient. Someone answered my question on IRC, suggesting to just use some NAT rules for redirecting the traffic. I will probably just do it this way, even though I would have preferred a solution that works without root privileges.

Here are the nftables rules that forward all outgoing traffic to port 139 to another port (44139 in this example):

table ip nat {
        chain output {
                type nat hook output priority filter + 1; policy accept;
                # replace 44139 with the port you would like the SMB via NetBIOS traffic to be redirected to
                tcp dport 139 redirect to :44139
        }
}
cddmp commented 2 years ago

I'm sorry that the Samba tools make it that hard. :/ An idea that came to my mind is, one could LD_PRELOAD the socket. That way one could silently change the target port and the Samba tools would not notice that. I'm not sure if it works but in theory it could work. You could experiment with something like that (if you still want to): https://github.com/iqe/ld-preload-socket

Thank you for your efforts, btw.! :)

cddmp commented 2 years ago

I just gave it a try, this seems to work: LD_PRELOAD=/home/user/tools/ld-preload-socket/ld-preload-socket.so LD_PRELOAD_SOCKET_INET_PORT_MAP="445:11445,139:11139" smbclient -L '//192.168.123.123/share' -U 'user%pass'

In this case SMB is listening on 11445 and SMB over NetBIOS is listening on 11139, but smbclient thinks the ports are 445 and 139. No root needed for that. This could be implemented, but would require to deliver the library as part of enum4linux-ng. I need a similar LD_PRELOAD approach for a Kerberos issue anyway, though my original plan was to use something like resolv_wrapper, which is part of many linux distributions anyway (so people can install a proper package, rather than using a hacky library). Let's see. :)