-
Notifications
You must be signed in to change notification settings - Fork 73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Trouble connecting with username and password #289
Comments
The problem here is that impacket performs NTLM authentication but does not offer and signing capabilities so the Negotiate wrapped NTLM token is unable to sign the mech list MIC. The other problem is SMB signing also requires this feature from the NTLM auth so that will fail once it gets there. What you can try to use plain NTLM auth (without the Negotiate wrapping) and disable signing is by setting: smbclient.register_session(…, auth_protocol='ntlm', require_signing=False) |
import smbclient
smbclient.register_session(
server="127.0.0.1", username="username", password="password", port=8445,
auth_protocol="ntlm", require_signing=False) results in: Exception in thread msg_worker-127.0.0.1:8445:
Traceback (most recent call last):
File "/home/user/.local/lib/python3.10/site-packages/smbprotocol/connection.py", line 1369, in _process_message_thread
self.verify_signature(header, session_id)
File "/home/user/.local/lib/python3.10/site-packages/smbprotocol/connection.py", line 1163, in verify_signature
raise SMBException(f"Failed to find session {session_id} for message verification")
smbprotocol.exceptions.SMBException: Failed to find session 0 for message verification
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
self.run()
File "/usr/lib/python3.10/threading.py", line 953, in run
self._target(*self._args, **self._kwargs)
File "/home/user/.local/lib/python3.10/site-packages/smbprotocol/connection.py", line 1406, in _process_message_thread
self.disconnect(False)
File "/home/user/.local/lib/python3.10/site-packages/smbprotocol/connection.py", line 957, in disconnect
self._t_worker.join(timeout=2)
File "/usr/lib/python3.10/threading.py", line 1093, in join
raise RuntimeError("cannot join current thread")
RuntimeError: cannot join current thread
Failed to close connection 127.0.0.1:8445
Traceback (most recent call last):
File "/home/user/.local/lib/python3.10/site-packages/smbclient/_pool.py", line 445, in reset_connection_cache
connection.disconnect()
File "/home/user/.local/lib/python3.10/site-packages/smbprotocol/connection.py", line 952, in disconnect
session.disconnect(True, timeout=timeout)
File "/home/user/.local/lib/python3.10/site-packages/smbprotocol/session.py", line 421, in disconnect
res = self.connection.receive(request, timeout=timeout)
File "/home/user/.local/lib/python3.10/site-packages/smbprotocol/connection.py", line 1028, in receive
self._check_worker_running() # The worker may have failed while waiting for the response, check again
File "/home/user/.local/lib/python3.10/site-packages/smbprotocol/connection.py", line 1184, in _check_worker_running
raise self._t_exc
File "/home/user/.local/lib/python3.10/site-packages/smbprotocol/connection.py", line 1369, in _process_message_thread
self.verify_signature(header, session_id)
File "/home/user/.local/lib/python3.10/site-packages/smbprotocol/connection.py", line 1163, in verify_signature
raise SMBException(f"Failed to find session {session_id} for message verification")
smbprotocol.exceptions.SMBException: Failed to find session 0 for message verification I am also wondering why it works out of the box with the system-insalled smbclient 4.15.13-Ubuntu. Has it signing disabled by default? |
I have "fixed" it like this: --- /home/user/.local/lib/python3.10/site-packages/smbprotocol/connection.py 2024-10-04 09:06:52.183148226 +0200
+++ /home/user/.local/lib/python3.10/site-packages/smbprotocol/connection.py 2024-10-04 09:06:23.911091124 +0200
@@ -1155,6 +1155,7 @@
or not flags.has_flag(Smb2Flags.SMB2_FLAGS_SIGNED)
or status == NtStatus.STATUS_PENDING
or command == Commands.SMB2_SESSION_SETUP
+ or not self.require_signing
):
return
I'm not sure if what I am doing is right and whether it should be merged, but seeing that the system smbclient works out of the box, I'd want to see it also work similarly easily with smbprotocol. import smbclient
smbclient.register_session(
server="127.0.0.1", username="username", password="password",
port=8445, auth_protocol="ntlm", require_signing=False, encrypt=False)
print(smbclient.listdir("127.0.0.1//test/", port=8445))' This now prints folders successfully. Although, I was confused that I had to respecify the port (and IP) again. Is there some object-oriented API with which I don't have to respecify connection details for each command? I am also confused about this error message in my initial post:
It implies to me that there is indeed some signing going on and working but failing. |
I've had a look at the code and unfortunately it does not seem to be possible, you must always specify the I'll have to setup a test server to try out impacket to see why it doesn't work and what needs to be done to allow disabling the signing request. |
I've opened fortra/impacket#1826 to fix up the |
I guess with your explanation one could also file this as a bug in impacket. I just thought that this was a bug here because it worked with smbclient. I'm also not very fixed on impacket. I just needed something for local and CI testing for ratarmount that could be set up quickly and without root privileges. Impacket came up via Google and was much easier to set up than the fully-fledged samba package. |
So I've done two things on Impacket
|
I've opened #291 which adds the workaround for the session id lookup. I've tested it locally but happy if you wish to try it out yourself. |
Thank you so much for fixing this in impacket and smbprotocol! Setup: python3 -m pip install --user --force-reinstall \
'git+https://github.com/jborean93/impacket.git@smb-ntlm-flags#egginfo=impacket'
python3 -m pip install --user --force-reinstall \
'git+https://github.com/jborean93/smbprotocol.git@impacket-session-di#egginfo=smbprotocol'
mkdir /tmp/sambashare
echo foo > /tmp/sambashare/bar
echo bar > /tmp/sambashare/foo
echo mimi > /tmp/sambashare/mimi
wget 'https://github.com/fortra/impacket/raw/27e7e7478df5d3d3bb12923055a7d8b614825ff4/examples/smbserver.py'
python3 smbserver.py -smb2support -username username -password password -ip 127.0.0.1 -port 8445 test /tmp/sambashare Access via Python: import smbclient
server = "127.0.0.1"
port = 8445
smbclient.register_session(
server=server, username="username", password="password", port=port,
auth_protocol='ntlm', require_signing=False,
)
print(smbclient.listdir(f"//{server}/test", port=port))
for name in ['mimi', 'foo', 'bar']:
with smbclient.open_file(f"//{server}/test/{name}", port=port, mode="rb") as file:
print(f"Name: {name} -> Contents: {file.read()}") Output:
It seems to work mostly, but for some reason, Test with smbclient:
|
I’ll have to debug the listdir response to see why it’s not showing all three entries. Thanks for confirming the others work for you. |
It's another bug in Impacket's smbserver, the result does not set the next entry offset value in the query response payload and thus the client thinks there is only 1 result. I've opened fortra/impacket#1831 which fixes the problem for me and the return result contains the expected values. The |
Urgh, I'm really sorry about all those bugs originating from a foreign project. I would have thought that SMB was sufficiently specified to avoid such issues between different client and server implementations. I guess smbclient is just too lenient with misbehaving servers. Thank you yet again. I can confirm that it works with:
Output:
|
That's all good, I think Impacket is more focused on netsec like work so it's not too surprising it has some edge cases. The fact that it works in general as an SMB server is pretty impressive and coming across these bugs is helpful for the entire ecosystem. It's fun to challenge my assumptions and also to fix these things so it's an overall positive :) |
I am hesistant to mention this, but for completeness sake: While my example above still works with all the workarounds, I get the signature failure again when trying import smbclient
server = "127.0.0.1"
port = 8445
smbclient.ClientConfig(auth_protocol='ntlm', require_signing=False)
smbclient.register_session(
server=server, username="username", password="password", port=port,
auth_protocol='ntlm', require_signing=False,
)
print(smbclient.listdir(f"//{server}/test", port=port)) # Works
print(smbclient.stat(f"//{server}/test", port=port)) # Error Output: ['mimi', 'bar', 'foo']
Exception in thread msg_worker-127.0.0.1:8445:
Traceback (most recent call last):
File "~/.local/lib/python3.12/site-packages/smbprotocol/connection.py", line 1373, in _process_message_thread
self.verify_signature(header, session_id)
File "~/.local/lib/python3.12/site-packages/smbprotocol/connection.py", line 1176, in verify_signature
raise SMBException(
smbprotocol.exceptions.SMBException: Server message signature could not be verified: 2c71c3516494658c9ec0e9be0c2f91b4 != fef82f7840703aa13afe781897a5c043
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.12/threading.py", line 1073, in _bootstrap_inner
self.run()
File "/usr/lib/python3.12/threading.py", line 1010, in run
self._target(*self._args, **self._kwargs)
File "~/.local/lib/python3.12/site-packages/smbprotocol/connection.py", line 1409, in _process_message_thread
self.disconnect(False)
File "~/.local/lib/python3.12/site-packages/smbprotocol/connection.py", line 957, in disconnect
self._t_worker.join(timeout=2)
File "/usr/lib/python3.12/threading.py", line 1144, in join
raise RuntimeError("cannot join current thread")
RuntimeError: cannot join current thread
Traceback (most recent call last):
File "/media/f/Beruf/ratarmount/test-smb.py", line 10, in <module>
print(smbclient.stat(f"//{server}/test", port=port)) # Error
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "~/.local/lib/python3.12/site-packages/smbclient/_os.py", line 600, in stat
with SMBFileTransaction(raw) as transaction:
File "~/.local/lib/python3.12/site-packages/smbclient/_io.py", line 260, in __exit__
self.commit()
File "~/.local/lib/python3.12/site-packages/smbclient/_io.py", line 296, in commit
res = func(requests[idx])
^^^^^^^^^^^^^^^^^^^
File "~/.local/lib/python3.12/site-packages/smbprotocol/open.py", line 1168, in _create_response
response = self.connection.receive(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "~/.local/lib/python3.12/site-packages/smbprotocol/connection.py", line 1028, in receive
self._check_worker_running() # The worker may have failed while waiting for the response, check again
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "~/.local/lib/python3.12/site-packages/smbprotocol/connection.py", line 1184, in _check_worker_running
raise self._t_exc
File "~/.local/lib/python3.12/site-packages/smbprotocol/connection.py", line 1373, in _process_message_thread
self.verify_signature(header, session_id)
File "~/.local/lib/python3.12/site-packages/smbprotocol/connection.py", line 1176, in verify_signature
raise SMBException(
smbprotocol.exceptions.SMBException: Server message signature could not be verified: 2c71c3516494658c9ec0e9be0c2f91b4 != fef82f7840703aa13afe781897a5c043 |
The first problem is due to Impacket and how it generates the signatures for a compound response. I've sent a PR to fix up their logic so the correct signatures are generated fortra/impacket#1834. Unfortunately even after fixing that there are still some further errors
The buffer problem here comes from the This is because Impacket does not support 2 of the file info classes that
I'll add in the logic to handle a "default" value for this particular buffer but until Impacket implements those 2 info classes (and our bugfixes) it won't work with the An alternative to this is to use the for entry in smbclient.scandir(r"\\localhost\test", port=8445):
print(entry.smb_info) This is supported by Impacket and is more efficient than listing the directory with |
Re-opening to deal with |
Ok to sum up this issue:
|
Hello,
I tried to set up a simple server and access it with:
However, I am unable to get it to work with smbprotocol. I tried to follow the example in the ReadMe:
But, I only get:
Out of desperation and without understanding, I also tried with
auth_protocol="ntlm"
given toregister_session
but only got:The text was updated successfully, but these errors were encountered: