From 7b8e03ef3ef83c575df37ff435fe493a5ccb83a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Thu, 12 Nov 2026 13:58:01 +0100 Subject: [PATCH] Fix for MSSQL row retrieval losing duplicates (OFFSET/FETCH for 2012+ and Azure) --- lib/core/agent.py | 5 +++++ lib/core/settings.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/core/agent.py b/lib/core/agent.py index 2e44b910c..37e24a6fc 100644 --- a/lib/core/agent.py +++ b/lib/core/agent.py @@ -1267,6 +1267,11 @@ class Agent(object): orderBy = limitedQuery[limitedQuery.index(" ORDER BY "):] limitedQuery = limitedQuery[:limitedQuery.index(" ORDER BY ")] + # Note: Microsoft SQL Server 2012+ (and Azure) supports OFFSET/FETCH (row position based), while the (old) NOT IN forging is value based (i.e. collapses duplicate values) + if Backend.isDbms(DBMS.MSSQL) and (Backend.isVersionGreaterOrEqualThan("2012") or Backend.isVersionWithin(("Azure",))) and not re.search(r"(?i)\A(SELECT\s+)?(TOP|DISTINCT)\b", limitedQuery): + limitedQuery = "%s%s OFFSET %d ROWS FETCH NEXT 1 ROWS ONLY" % (limitedQuery, orderBy or " ORDER BY %s" % (uniqueField or '1'), num) + return limitedQuery + notDistincts = re.findall(r"DISTINCT[\(\s+](.+?)\)*\s+", limitedQuery, re.I) for notDistinct in notDistincts: diff --git a/lib/core/settings.py b/lib/core/settings.py index eb0d4e4d5..a8f5f7a95 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -19,7 +19,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.11.24" +VERSION = "1.10.11.25" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)