Nmap Development mailing list archives
Bug in SMB when multiple scripts are connecting to same host
From: Chris Woodbury <chris3e3 () gmail com>
Date: Mon, 7 Feb 2011 19:28:18 -0600
I've found what I think is a bug in the SMB library, which gets triggered in the following situation: 1. Multiple scripts/script instances are running concurrently against the same host via SMB and are in smb.start_session_basic()/start_session_extended() at the same time. 2. The first entry in the SMB accounts list (nmap.registry[ IP ][ "smbaccounts" ] cannot log in. 3. There are no username overrides. In this situation, script #1 gets the first account off the list and tries to authenticate (unsuccessfully, as it will turn out). The network I/O causes a switch to script #2, which also gets the first account off the list and tries to authenticate (unsuccessfully as well, of course). The scripts each get going again and both make it down to the point where it is recognized that authentication has failed (beginning on line 1216 or 1384) and smbauth.next_account() and smbauth.get_account() are called to get the next account to try to authenticate with. Here is the problem. Both scripts have realized that their authentication attempts failed and call next_account(), but next_account() and get_account() work on a list of accounts that is shared for the host. Thus, script #1 gets the second account on the list, but script #2 gets the *third* account on the list. I have attached a script that should demonstrate this. If you make another copy (e.g. testsmb2.nse) and run them both against a host that allows anonymous logins (e.g. nmap -d2 -p 445 --script testsmb,testsmb2 <host>), you should see one succeed and ther other fail with "No accounts left to try." You may need to run in a couple times to get this to happen. Off the top of my head, it seems that this might be solved by making the list of accounts (or the index) tied to the smbstate (and thus specific to each script instance), or by using a mutex. I won't pretend to understand SMB and the smb libraries like Ron does, so I haven't tried to patch this myself. Please let me know if I've missed or misunderstood anything, or if anyone has questions. -chris Illustrative scenario: Four scripts are attempting to connect to a share that is accessible with the anonymous login (i.e. null session). No SMB credentials are given or discovered. The scripts aren't doing anything fancy and are using the high-level SMB functions (e.g. start_session_ex() ). 1. Script #1 starts first (the others are "started" but don't run until Script #1 makes a network I/O call). 2. Script #1 calls smb.start_session_ex(), which calls smb.start(), which calls smbauth.init_account(), which populates the account list for the host with { guest, anonymous }. 3. Script #1's smb.start_session_ex() eventually calls smb.start_session(), which in this example calls smb.start_session_extended(). This calls smbauth.get_account(), retrieving the guest account, which is then used in an authentication attempt. 4. Script #1's authentication attempt is network I/O, so execution switches to Script #2, which gets to the same point as Script #1, also attempting to log in with the guest account. 5. The same for Script #3. 6. Execution switches back to Script #1, which sees that its login attempt failed, so it calls smbauth.next_account() [smb.lua line 1386], which moves to the anonymous login. Script #1 then calls smb.get_account() to get the new account to try, and loops back around to make an authentication attempt with it. 7. Execution switches to Script #2, which does the same thing, except that its call to next_account() exhausts the account list. Its call to smb.get_account() gets an error saying there are "No accounts left to try", which causes the original call to smb.start_session_ex() to fail. 8. Execution switches to Script #1, which just authenticated with the anonymous login, which was successful. Its call to smb.start_session_ex() returns successfully. 9. Execution switches to Script #3, which does the same thing as Script #2 in step 7. Its call to smb.start_session_ex() also fails with "No accounts left to try". 10. Execution switches to Script #4, which has been waiting patiently. Like the others, it starts with a call to smb.start_session_ex(), but when it gets to the first call to smbauth.get_account() [line 1257], there are no more accounts, and Script #4 also fails with "No accounts left to try". Thus, out of four scripts, only one of them was actually able to get and use the valid credentials that were in the account list.
Attachment:
testsmb.nse
Description:
_______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://seclists.org/nmap-dev/
Current thread:
- Bug in SMB when multiple scripts are connecting to same host Chris Woodbury (Feb 07)
- Re: Bug in SMB when multiple scripts are connecting to same host Ron (Feb 27)
- Re: Bug in SMB when multiple scripts are connecting to same host Chris Woodbury (Feb 28)
- Re: Bug in SMB when multiple scripts are connecting to same host David Fifield (Mar 14)
- Re: Bug in SMB when multiple scripts are connecting to same host Ron (Mar 15)
- Re: Bug in SMB when multiple scripts are connecting to same host Chris Woodbury (Mar 31)
- Re: Bug in SMB when multiple scripts are connecting to same host Ron (Mar 31)
- Re: Bug in SMB when multiple scripts are connecting to same host Chris Woodbury (Feb 28)
- Re: Bug in SMB when multiple scripts are connecting to same host Ron (Feb 27)