Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,30 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: [ 'pypy-2.7', '3.8', '3.14' ]
exclude:
include:
- os: ubuntu-latest
python-version: "pypy-2.7"
- os: macos-latest
python-version: 'pypy-2.7'
python-version: "3.8"
- os: windows-latest
python-version: "3.14"

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Basic import test
run: python -c "import sqlmap; import sqlmapapi"

- name: Smoke test
run: python sqlmap.py --smoke

- name: Vuln test
run: python sqlmap.py --vuln
Binary file modified data/shell/backdoors/backdoor.asp_
Binary file not shown.
Binary file modified data/shell/backdoors/backdoor.aspx_
Binary file not shown.
Binary file modified data/shell/backdoors/backdoor.cfm_
Binary file not shown.
Binary file modified data/shell/backdoors/backdoor.jsp_
Binary file not shown.
Binary file modified data/shell/backdoors/backdoor.php_
Binary file not shown.
Binary file modified data/shell/stagers/stager.asp_
Binary file not shown.
Binary file modified data/shell/stagers/stager.aspx_
Binary file not shown.
Binary file modified data/shell/stagers/stager.cfm_
Binary file not shown.
Binary file modified data/shell/stagers/stager.jsp_
Binary file not shown.
Binary file modified data/shell/stagers/stager.php_
Binary file not shown.
112 changes: 56 additions & 56 deletions data/txt/sha256sums.txt

Large diffs are not rendered by default.

Binary file modified data/udf/mysql/linux/32/lib_mysqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/mysql/linux/64/lib_mysqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/mysql/windows/32/lib_mysqludf_sys.dll_
Binary file not shown.
Binary file modified data/udf/mysql/windows/64/lib_mysqludf_sys.dll_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/32/10/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/32/11/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/32/8.2/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/32/8.3/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/32/8.4/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/32/9.0/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/32/9.1/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/32/9.2/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/32/9.3/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/32/9.4/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/32/9.5/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/32/9.6/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/64/10/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/64/11/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/64/12/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/64/8.2/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/64/8.3/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/64/8.4/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/64/9.0/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/64/9.1/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/64/9.2/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/64/9.3/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/64/9.4/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/64/9.5/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/linux/64/9.6/lib_postgresqludf_sys.so_
Binary file not shown.
Binary file modified data/udf/postgresql/windows/32/8.2/lib_postgresqludf_sys.dll_
Binary file not shown.
Binary file modified data/udf/postgresql/windows/32/8.3/lib_postgresqludf_sys.dll_
Binary file not shown.
Binary file modified data/udf/postgresql/windows/32/8.4/lib_postgresqludf_sys.dll_
Binary file not shown.
Binary file modified data/udf/postgresql/windows/32/9.0/lib_postgresqludf_sys.dll_
Binary file not shown.
2 changes: 1 addition & 1 deletion extra/cloak/cloak.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
xrange = range
ord = lambda _: _

KEY = b"wr36EPIvaR7ZDfb4"
KEY = b"ZCuk6GdHSj4KtgDq"

def xor(message, key):
return b"".join(struct.pack('B', ord(message[i]) ^ ord(key[i % len(key)])) for i in range(len(message)))
Expand Down
Binary file modified extra/icmpsh/icmpsh.exe_
Binary file not shown.
Binary file modified extra/runcmd/runcmd.exe_
Binary file not shown.
Binary file modified extra/shellcodeexec/windows/shellcodeexec.x32.exe_
Binary file not shown.
2 changes: 2 additions & 0 deletions lib/controller/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -1377,13 +1377,15 @@ def checkWaf():
kb.choices.redirect = REDIRECTION.YES
kb.resendPostOnRedirect = False
conf.timeout = IPS_WAF_CHECK_TIMEOUT
kb.checkWafMode = True

try:
retVal = (Request.queryPage(place=place, value=value, getRatioValue=True, noteResponseTime=False, silent=True, raise404=False, disableTampering=True)[1] or 0) < IPS_WAF_CHECK_RATIO
except SqlmapConnectionException:
retVal = True
finally:
kb.matchRatio = None
kb.checkWafMode = False

conf.timeout = popValue()
kb.resendPostOnRedirect = popValue()
Expand Down
5 changes: 4 additions & 1 deletion lib/core/option.py
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,7 @@ def _setSocketPreConnect():

def _thread():
while kb.get("threadContinue") and not conf.get("disablePrecon"):
done = False
try:
with kb.locks.socket:
keys = list(socket._ready.keys())
Expand All @@ -1076,6 +1077,7 @@ def _thread():
if q is not None and len(q) < SOCKET_PRE_CONNECT_QUEUE_SIZE:
q.append((s, time.time()))
s = None
done = True

if s is not None:
try:
Expand All @@ -1088,7 +1090,7 @@ def _thread():
except:
pass
finally:
time.sleep(0.01)
time.sleep(0.01 if not done else 0.001)

def create_connection(*args, **kwargs):
retVal = None
Expand Down Expand Up @@ -2086,6 +2088,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.chars.stop = "%s%s%s" % (KB_CHARS_BOUNDARY_CHAR, randomStr(length=3, alphabet=KB_CHARS_LOW_FREQUENCY_ALPHABET), KB_CHARS_BOUNDARY_CHAR)
kb.chars.at, kb.chars.space, kb.chars.dollar, kb.chars.hash_ = ("%s%s%s" % (KB_CHARS_BOUNDARY_CHAR, _, KB_CHARS_BOUNDARY_CHAR) for _ in randomStr(length=4, lowercase=True))

kb.checkWafMode = False
kb.choices = AttribDict(keycheck=False)
kb.codePage = None
kb.commonOutputs = None
Expand Down
1 change: 1 addition & 0 deletions lib/core/optiondict.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"safeReqFile": "string",
"safeFreq": "integer",
"skipUrlEncode": "boolean",
"skipXmlEncode": "boolean",
"csrfToken": "string",
"csrfUrl": "string",
"csrfMethod": "string",
Expand Down
9 changes: 6 additions & 3 deletions lib/core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from thirdparty import six

# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.10.2.6"
VERSION = "1.10.2.14"
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)
Expand Down Expand Up @@ -122,7 +122,10 @@
PRECONNECT_INCOMPATIBLE_SERVERS = ("SimpleHTTP", "BaseHTTP")

# Identify WAF/IPS inside limited number of responses (Note: for optimization purposes)
IDENTYWAF_PARSE_LIMIT = 10
IDENTYWAF_PARSE_COUNT_LIMIT = 10

# Identify WAF/IPS inside limited size of responses
IDENTYWAF_PARSE_PAGE_LIMIT = 4 * 1024

# Maximum sleep time in "Murphy" (testing) mode
MAX_MURPHY_SLEEP_TIME = 3
Expand Down Expand Up @@ -779,7 +782,7 @@
# For preventing MemoryError exceptions (caused when using large sequences in difflib.SequenceMatcher)
MAX_DIFFLIB_SEQUENCE_LENGTH = 10 * 1024 * 1024

# Page size threshold used in heuristic checks (e.g. getHeuristicCharEncoding(), identYwaf, htmlParser, etc.)
# Page size threshold used in heuristic checks (e.g. getHeuristicCharEncoding(), htmlParser, etc.)
HEURISTIC_PAGE_SIZE_THRESHOLD = 64 * 1024

# Maximum (multi-threaded) length of entry in bisection algorithm
Expand Down
8 changes: 8 additions & 0 deletions lib/core/target.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,14 @@ def _setHashDB():
errMsg = "unable to flush the session file ('%s')" % getSafeExString(ex)
raise SqlmapFilePathException(errMsg)

for suffix in ("-shm", "-wal"):
leftover = conf.hashDBFile + suffix
if os.path.exists(leftover):
try:
os.remove(leftover)
except OSError:
pass

conf.hashDB = HashDB(conf.hashDBFile)

def _resumeHashDBValues():
Expand Down
3 changes: 3 additions & 0 deletions lib/parse/cmdline.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,9 @@ def cmdLineParser(argv=None):
request.add_argument("--skip-urlencode", dest="skipUrlEncode", action="store_true",
help="Skip URL encoding of payload data")

request.add_argument("--skip-xmlencode", dest="skipXmlEncode", action="store_true",
help="Skip safe encoding of payload data for SOAP/XML")

request.add_argument("--csrf-token", dest="csrfToken",
help="Parameter used to hold anti-CSRF token")

Expand Down
7 changes: 4 additions & 3 deletions lib/request/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@
from lib.core.settings import DEFAULT_COOKIE_DELIMITER
from lib.core.settings import EVENTVALIDATION_REGEX
from lib.core.settings import HEURISTIC_PAGE_SIZE_THRESHOLD
from lib.core.settings import IDENTYWAF_PARSE_LIMIT
from lib.core.settings import IDENTYWAF_PARSE_COUNT_LIMIT
from lib.core.settings import IDENTYWAF_PARSE_PAGE_LIMIT
from lib.core.settings import MAX_CONNECTION_TOTAL_SIZE
from lib.core.settings import META_CHARSET_REGEX
from lib.core.settings import PARSE_HEADERS_LIMIT
Expand Down Expand Up @@ -395,8 +396,8 @@ def processResponse(page, responseHeaders, code=None, status=None):
if msg:
logger.warning("parsed DBMS error message: '%s'" % msg.rstrip('.'))

if not conf.skipWaf and kb.processResponseCounter < IDENTYWAF_PARSE_LIMIT:
rawResponse = "%s %s %s\n%s\n%s" % (_http_client.HTTPConnection._http_vsn_str, code or "", status or "", "".join(getUnicode(responseHeaders.headers if responseHeaders else [])), page[:HEURISTIC_PAGE_SIZE_THRESHOLD])
if not conf.skipWaf and kb.processResponseCounter < IDENTYWAF_PARSE_COUNT_LIMIT:
rawResponse = "%s %s %s\n%s\n%s" % (_http_client.HTTPConnection._http_vsn_str, code or "", status or "", "".join(getUnicode(responseHeaders.headers if responseHeaders else [])), page[:IDENTYWAF_PARSE_PAGE_LIMIT] if not kb.checkWafMode else page[:HEURISTIC_PAGE_SIZE_THRESHOLD])

with kb.locks.identYwaf:
identYwaf.non_blind.clear()
Expand Down
19 changes: 11 additions & 8 deletions lib/request/connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,17 +227,18 @@ def _retryProxy(**kwargs):

@staticmethod
def _connReadProxy(conn):
retVal = b""
parts = []

if not kb.dnsMode and conn:
headers = conn.info()
if kb.pageCompress and headers and hasattr(headers, "getheader") and (headers.getheader(HTTP_HEADER.CONTENT_ENCODING, "").lower() in ("gzip", "deflate") or "text" not in headers.getheader(HTTP_HEADER.CONTENT_TYPE, "").lower()):
retVal = conn.read(MAX_CONNECTION_TOTAL_SIZE)
if len(retVal) == MAX_CONNECTION_TOTAL_SIZE:
part = conn.read(MAX_CONNECTION_TOTAL_SIZE)
if len(part) == MAX_CONNECTION_TOTAL_SIZE:
warnMsg = "large compressed response detected. Disabling compression"
singleTimeWarnMessage(warnMsg)
kb.pageCompress = False
raise SqlmapCompressionException
parts.append(part)
else:
while True:
if not conn:
Expand All @@ -252,18 +253,20 @@ def _connReadProxy(conn):
warnMsg = "large response detected. This could take a while"
singleTimeWarnMessage(warnMsg)
part = re.sub(getBytes(r"(?si)%s.+?%s" % (kb.chars.stop, kb.chars.start)), getBytes("%s%s%s" % (kb.chars.stop, LARGE_READ_TRIM_MARKER, kb.chars.start)), part)
retVal += part
parts.append(part)
else:
retVal += part
parts.append(part)
break

if len(retVal) > MAX_CONNECTION_TOTAL_SIZE:
if sum(len(_) for _ in parts) > MAX_CONNECTION_TOTAL_SIZE:
warnMsg = "too large response detected. Automatically trimming it"
singleTimeWarnMessage(warnMsg)
break

if conf.yuge:
retVal = YUGE_FACTOR * retVal
parts = YUGE_FACTOR * parts

retVal = b"".join(parts)

return retVal

Expand Down Expand Up @@ -1113,7 +1116,7 @@ def queryPage(value=None, place=None, content=False, getRatioValue=False, silent
logger.log(CUSTOM_LOGGING.PAYLOAD, safecharencode(payload.replace('\\', BOUNDARY_BACKSLASH_MARKER)).replace(BOUNDARY_BACKSLASH_MARKER, '\\'))

if place == PLACE.CUSTOM_POST and kb.postHint:
if kb.postHint in (POST_HINT.SOAP, POST_HINT.XML):
if kb.postHint in (POST_HINT.SOAP, POST_HINT.XML) and not conf.skipXmlEncode:
# payloads in SOAP/XML should have chars > and < replaced
# with their HTML encoded counterparts
payload = payload.replace("&#", SAFE_HEX_MARKER)
Expand Down
4 changes: 4 additions & 0 deletions sqlmap.conf
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ safeFreq = 0
# Valid: True or False
skipUrlEncode = False

# Skip safe (HTML) encoding of payload data for SOAP/XML.
# Valid: True or False
skipXmlEncode = False

# Parameter used to hold anti-CSRF token.
csrfToken =

Expand Down
Loading