SQL Browser detection for MSSQL protocol#733
Conversation
|
Man that is a fantastic update! I wasn't aware of this MSSQL Browser thing!! |
Thanks ! SQL Browser is not enabled by default and requires a bit of setup, and I haven't been able to test it outside of the lab yet to assess the efficiency of scanning an additional UDP port by default. I usually blind spray mssql for initial access, and I'm sure I missed some instances because I didn't know about the dynamic port until yesterday... The SQL server can still run on a random port even if the SQL browser is disabled, so it's not a 100% guaranteed hit, but it will certainly improve automatic discovery. |
|
Yeah don't worry about the testing, I'm actually finishing integrating encryption and channel binding on Impacket, and then on NXC, myself so I have got a lab on which I can test your PR as well! Will look ASAP :) |
|
Very interesting, thanks for the PR! Do you have any resources about that topic that you could share? |
Not so much, I just learned about it 😅 SQL Browser uses the TDS protocol on UDP 1434 : https://learn.microsoft.com/en-us/sql/relational-databases/security/networking/tds-8?view=sql-server-ver17 So in reality, the protocol is TDS. Yet MS states it uses SQL Server Resolution Protocol (SSRP)... Confusing. Impacket already implements TDS behind the scenes. I'm unsure if there's more setup required for encrypted connections or if it works out of the box. Instances can be hidden from SQL Browser, meaning the service can run but not list any instances. There's probably a way to try catch getInstances to detect whether the service actually runs THEN enumerating instances, rather than only relying on the array size. But I don't think that makes a huge operational difference. MSDOCS for SQL Browser : https://learn.microsoft.com/en-us/sql/tools/configuration-manager/sql-server-browser-service?view=sql-server-ver16 I'll see what I can do to move the detection to enum_host_info ! |
|
Oh wait there's something about DAC that we could definitely look into : https://learn.microsoft.com/en-us/sql/database-engine/configure-windows/diagnostic-connection-for-database-administrators?view=sql-server-ver16 It runs on the same 1434 port and potentially gives access to the database even when it's not directly exposed. I'll try to look into it later today. |
|
It's getting more complicated than I thought ! SQL browser also lists named-pipe SQL instances ! (which is great) For now I'll only fallback to TCP until I understand how we can fallback to named pipes without breaking other modules. |
Hey ;) Leaving this here just in case : |
|
I'll be looking into this one that week mate! Sorry for the long delay but I had to implement the CBT thing before ahah! |
|
Hey man! So I'm back at this PR which I will work on. Thing is there are a lot of stuff I gotta catch up because I have got limited knowledges about MSSQL instances. I'll dig that and let you know about my progress ;)! |
|
@mrsheepsheep any thoughts on that ? |
|
Hey @mrsheepsheep any news ? :P |
|
Hey !
I'm so busy at work that I always give up on relogging into my personal
Github account, sorry !
Lemme check next week :)
Le jeu. 26 mars 2026 à 18:35, Deft_ ***@***.***> a écrit :
… *Dfte* left a comment (Pennyw0rth/NetExec#733)
<#733?email_source=notifications&email_token=ABFUB4NMXGTLRZNAMP3BFUD4SVS4RA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTIMJTGY4DOMBWGIY2M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJNLQOJPWG33NNVSW45C7N5YGK3S7MNWGSY3L#issuecomment-4136870621>
Hey @mrsheepsheep <https://github.com/mrsheepsheep> any news ? :P
—
Reply to this email directly, view it on GitHub
<#733?email_source=notifications&email_token=ABFUB4NMXGTLRZNAMP3BFUD4SVS4RA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTIMJTGY4DOMBWGIY2M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJNLQOJPWG33NNVSW45C7N5YGK3S7MNWGSY3L#issuecomment-4136870621>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABFUB4IIYHLSKSAFVX6W37T4SVS4RAVCNFSM6AAAAAB7DYNHWSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHM2DCMZWHA3TANRSGE>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
|
The @Dfte I've sent you an invite so that you can commit the PR as well (I think ?) My thought right now is whether we should do SQL browser enumeration by default (especially when no SQL server was found), or shift this ability to the So to recap, I imagine it like this :
Then once we find a way to interact with the named pipes instances, we can just add a --instance to intercat directly with it, and a --np to also manually specify the namedpipe. |
Signed-off-by: Alexandre S. <mrsheepsheepandcie@gmail.com>
|
Looks good to me! I'll try to merge that on your branch ASAP :)! |
|
Alright so I have been thinking about all of that. My guess is that indeed the UDP timeout is an important factor but not forcing it will make people forget about that sql browser feature and miss huge opportunities. We can may be combine both worlds adding a nxc configuration option that says whether or not we launch the UDP discovery thing ? That's really something I would like to have as a default behaviour @NeffIsBack @azoxlpf I need some feedbacks there ahahah |
|
I was also thinking about a dirty way to suggest SQL browser existence without forcing it by default : re-add the SQL browser inside the banner, but mark it as Unknown until it's actually scanned. Future scans could ask the DB for the last known browser status and display the number of instances. It's unusual to interact with the DB this way but it could be a good mix to suggest the ability to enumerate SQL browser while keeping it off by default ? |
|
Off topic but I'm now thinking about a |
|
I’m broadly aligned with combining both approaches via a Proposal :
On the implementation side, re-calling |
I think I lean more to this side. Yes, scanning MSSQL with netexec is a thing, but honestly it is not designed to be a fast network scanner, but rather a tool that automates as much as possible with minimum required knowledge/effort about the exact details of what is happening. I agree that having an additional 2s of scanning time per host is bad, but with the trade off of missing instances (which seems like we pretty much all did until now), I would rather take the hit on scanning speed. Imo you should scan with nmap/nessus anyway, and then connect to discovered hosts (yes, that still has the problem of potentially missing the mssql browser, but my assumption would be that in most cases IF there is a browser we also have at least one DB running on the default port right?). We could still add a config option to disable that discovery if people prefer speed over usability, but imo that should be set to "discover_sql_browser = True" (or however you would call it) per default. Two technical details:
|
Actually, SQL browser is most likely to be enabled with SQL servers not running on the default port ! Also consider named pipe servers which may not have any TCP port at all, so the server is simply invisible unless you scan for SQL browser (and maybe RPC). In the end, named pipes are the final target of this NXC feature.
The getInstances creates an UDP socket, but it does not need the initial MSSQL connection to be established in the first place, so recreating a TDS object does not really reestablish a connection, but we can pass the
I strongly agree, I just need to figure out how to properly create a new standalone connection that fits within the NXC loop. Checklist to myself :
Any opinion on that ? |
|
I still believe we should enforce the sql browser scanning even tho it means a 2 second timeout. Because I agree, sql browsers will mostly be used by sysadmins that don't have to expose the 1433 port. Considering nxc is multi threaded, I don't care about the timeout. About that: Yes I'd keep the banner but I'm not sure I'd want to rely on the DB to expose the number of instances and their names |
Agreed, the DB has some stability issues with multi threading sometimes, so we should probably not rely on that.
I think I was confused about the reconnecting part and "connect to instances" code, but I guess that is for just connecting to the DBs after initial recon? Imo it would be less confusing if we would just reuse the existing tds object, but as it doesn't influence anything outside of |
Hi @mrsheepsheep, we talked about that PR internally and believe we should revert it to the part where enumeration is done no matter what. Because the information about the sql browser running is too much important to just be left behind in case you don't use the appropriate option. If that's ok with you I can take care of reverting and then making the PR a little bit cleaner. Let me know :) |
|
@Dfte No problem ! I'll let you handle the rest :) |
|
Hey! I'll be following this PR there #1200 but I'll make sure you'll get the credits as well because that's a fantastic feature to me so yeah... Thank you :p |
|
See you in 1200 ! |
















Description
Adds support for SQL Browser detection and automatic fallback to the dynamic SQL server port if only one instance is running.
This slows down the scan a bit but can detect MSSQL servers without a detailed port scan on each
I chose to add SQL Browser detection by default and added a blacklit flag
--no-sqlbrowser, but it can easily be changed to--sqlbrowserif it's more appropriate.When using
--portwith a non-default port, the fallback will be ignored. When multiple instances are detected, no fallback happens.We could also remove the port fallback part and simply report it and let the user rerun with
--port. Let me know what's best.Type of change
Setup guide for the review
OS : Windows Server 2022 with SQL Server Express installed
Expose the SQL server to the network : Open
SQL Server Network Configuration > Protocols for INSTANCENAMEEnabledto true and ensureListen Allis set toYesEnable the SQL Browser service : Open
SQL Server ServicesDisable the Windows Firewall if you're lazy (SQL Server rules are not added by default, this is for testing purposes only).
Restart the SQL Server service.
Note down the dynamic port used by SQL server :
You can now run a set of tests targeted at a single SQL server instance.
To add more instances, run
SQL Server 2022 Installation Center,Installation, clickNew SQL Server Standalone installation or..., selectThis PC > C: > SQL2022 > Express_ENUand follow instructions. Once the instance is installed, repeat the steps above for the new instance.Screenshots
Running on a
/21without--no-sqlbrowser(slower)Running on a
/21with--no-sqlbrowser(faster) yields no resultsThe fallback works as expected when running other modules like command execution :
--porthas priority and works as expectedMultiple instances setup
Checklist:
poetry run python -m ruff check . --preview, use--fixto automatically fix what it can)--rid-brutebecause test server was not domain-joined