Skip to content

SQL Browser detection for MSSQL protocol based on mrsheepsheep work#1200

Open
Dfte wants to merge 5 commits into
Pennyw0rth:mainfrom
Dfte:rework_sql_browser
Open

SQL Browser detection for MSSQL protocol based on mrsheepsheep work#1200
Dfte wants to merge 5 commits into
Pennyw0rth:mainfrom
Dfte:rework_sql_browser

Conversation

@Dfte
Copy link
Copy Markdown
Contributor

@Dfte Dfte commented Apr 14, 2026

Description

This PR is an original idea from @mrsheepsheep which allows connecting to the SQL browser if it is running. Basically, the SQL browser is listening on UDP port 1434 and can be reached to list all SQL instances available on a MSSQL server. Considering this SQL browser can be reached anonymously, it becomes a great asset for enumeration purposes.

image

This PR implements three differents usages:

  • The TCP server (port 1433) is not running, nxc mssql doesn't print the enum_host banner but still tries to connect to the SQL browser and prints found information:
image
  • The TCP server is running and the SQL browser is running as well, a new banner is added:
image
  • The TCP server is running, the SQL browser is running and the --list-instances option is used, prints all instances information:
image

Auto discovery of the SQL browser means connecting to a UDP port with a default timeout of 5 secondes. For that reason it is possible to disable the discovery using the following nxc config option:

image

Type of change

Insert an "x" inside the brackets for relevant items (do not delete options)

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Deprecation of feature or functionality
  • This change requires a documentation update
  • This requires a third party update (such as Impacket, Dploot, lsassy, etc)
  • This PR was created with the assistance of AI (list what type of assistance, tool(s)/model(s) in the description)

Checklist (WIP, none of these checks were made yet):

Insert an "x" inside the brackets for completed and relevant items (do not delete options)

  • I have ran Ruff against my changes (poetry: poetry run ruff check ., use --fix to automatically fix what it can)
  • I have added or updated the tests/e2e_commands.txt file if necessary (new modules or features are required to be added to the e2e tests)
  • If reliant on changes of third party dependencies, such as Impacket, dploot, lsassy, etc, I have linked the relevant PRs in those projects
  • I have linked relevant sources that describes the added technique (blog posts, documentation, etc)
  • I have performed a self-review of my own code (not an AI review)
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation (PR here: https://github.com/Pennyw0rth/NetExec-Wiki)

Signed-off-by: Deft_ <aurelien.chalot@protonmail.com>
@Dfte Dfte mentioned this pull request Apr 14, 2026
12 tasks
Signed-off-by: Deft_ <aurelien.chalot@protonmail.com>
@NeffIsBack NeffIsBack added the enhancement New feature or request label Apr 14, 2026
@NeffIsBack
Copy link
Copy Markdown
Member

Nice one, thanks! I'll take a closer look in the evening

@NeffIsBack
Copy link
Copy Markdown
Member

So from our chat and looking at the code, Imo we should abstract the information about the instances from the technique itself, meaning that I would:

  • Liste instances instead of "SqlBrowser:True", e.g. Instances:1 for normal connections and instances:x counting all existing instances if sqlbrowser exists (that one should include the default 1433 instance right?)
  • Always pick one instance as the "default" connection. This is obviously 1433, if available. Otherwise pick the first instance that is available by the sqlbrowser. Then we display the banner as normal, keeping consistency to the default 1433 instance and we also preserve the logic of having self.port, self.conn etc. available at all times.
  • Make switching to other instances possible with e.g. --instance 4, where the default instance is replaced with the enumerated (--instances) instance, keeping consistency and displaying the banner with the appropriate port etc.

TLDR; The end user doesn't specifically need to know how we enumerated the instances (sqlbrowser), just that there are more than 1 and that you can switch. We can print information that there is an "SQLBrowser" via some info/debug log if needed/wanted.

@Dfte
Copy link
Copy Markdown
Contributor Author

Dfte commented Apr 15, 2026

Problem is we can't do that for now because tds.py does not support SQL over named pipes. Hence, if the first instance is a named pipe one, we get blocked. To me we shouldn't specify any instance by default. Instead we tell the user the sql browser is running, provide an option to list the instances and then another option --instance to select which one he wants to use. Then we'll have to make a new connection form scratch.
But as for now it's not really possible to make the --instance one because Tds.py not supporting all possible connection types :/

Dfte and others added 2 commits April 15, 2026 14:46
patch broadcast address sql browser udp

Signed-off-by: Deft_ <aurelien.chalot@protonmail.com>
@Dfte
Copy link
Copy Markdown
Contributor Author

Dfte commented Apr 15, 2026

Last PR patches the ip.py parse_targets function which was incorrectly passing the broadcast address to scan.

From:

for ip in ip_network(target, strict=False)

to

for ip in ip_network(target, strict=False).hosts()

Thx @azoxlpf for the information (eyes)

@NeffIsBack
Copy link
Copy Markdown
Member

Problem is we can't do that for now because tds.py does not support SQL over named pipes. Hence, if the first instance is a named pipe one, we get blocked. To me we shouldn't specify any instance by default. Instead we tell the user the sql browser is running, provide an option to list the instances and then another option --instance to select which one he wants to use. Then we'll have to make a new connection form scratch. But as for now it's not really possible to make the --instance one because Tds.py not supporting all possible connection types :/

Not being able to support named pipes is unfortunate. Any experience how common that is? Perhaps we can get away to just skip these for now until someone invests the time to implement support for it. We could still try to select the instance and just tell the user "eh sorry, that instance is running via named pipes which isn't supported yet". Otherwise, how would you access the instances?

What would be the argument against selecting the first (possible) instance we get by default? Just makes it less work if you have the sqlbrowser available. To alert the user that there are others as well, we could do something like make the instance banner yellow if >2 are available, else green (similar to signing/smbv1 etc.).

@mrsheepsheep
Copy link
Copy Markdown

Any experience how common that is?

I think that's the biggest question of the feature : are SQL browser and named pipes widely used or is it just a niche feature ?

I'll ask the colleagues to run those scans on the next AD assessments in the following weeks to see if they find any.

@NeffIsBack
Copy link
Copy Markdown
Member

Any experience how common that is?

I think that's the biggest question of the feature : are SQL browser and named pipes widely used or is it just a niche feature ?

I know that we definitely have seen them, as my colleague told me that nessus reports the sql browser as well. I have no idea tho what instances are typically running behind these or even if there are more instances than just the default one.

@Dfte
Copy link
Copy Markdown
Contributor Author

Dfte commented Apr 20, 2026

I'd say that even if it's a niche feature, being able to expose these instances is important as it could be, during an internal assessment, the last resort to compromise the domain :P!
Once TDS8.0 on impacket is merged we'll work on the named pipe implementation anyway

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants