Skip to content

Commit 30f8d09

Browse files
committed
Implementation for an Issue sqlmapproject#70
1 parent 57f2fcc commit 30f8d09

File tree

8 files changed

+31
-8
lines changed

8 files changed

+31
-8
lines changed

lib/controller/checks.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ def genCmpPayload():
359359

360360
injectable = True
361361

362-
if not injectable and not conf.string and kb.pageStable:
362+
if not injectable and not any((conf.string, conf.notString, conf.regexp)) and kb.pageStable:
363363
trueSet = set(extractTextTagContent(truePage))
364364
falseSet = set(extractTextTagContent(falsePage))
365365
candidates = filter(None, (_.strip() if _.strip() in (kb.pageTemplate or "") and _.strip() not in falsePage else None for _ in (trueSet - falseSet)))
@@ -499,6 +499,7 @@ def genCmpPayload():
499499
injection.conf.textOnly = conf.textOnly
500500
injection.conf.titles = conf.titles
501501
injection.conf.string = conf.string
502+
injection.conf.notString = conf.notString
502503
injection.conf.regexp = conf.regexp
503504
injection.conf.optimize = conf.optimize
504505

lib/controller/controller.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ def start():
357357
if (len(kb.injections) == 0 or (len(kb.injections) == 1 and kb.injections[0].place is None)) \
358358
and (kb.injection.place is None or kb.injection.parameter is None):
359359

360-
if not conf.string and not conf.regexp and PAYLOAD.TECHNIQUE.BOOLEAN in conf.tech:
360+
if not any((conf.string, conf.notString, conf.regexp)) and PAYLOAD.TECHNIQUE.BOOLEAN in conf.tech:
361361
# NOTE: this is not needed anymore, leaving only to display
362362
# a warning message to the user in case the page is not stable
363363
checkStability()
@@ -527,7 +527,7 @@ def start():
527527
errMsg += "Please, consider usage of tampering scripts as "
528528
errMsg += "your target might filter the queries."
529529

530-
if not conf.string and not conf.regexp:
530+
if not conf.string and not conf.notString and not conf.regexp:
531531
errMsg += " Also, you can try to rerun by providing "
532532
errMsg += "either a valid value for option '--string' "
533533
errMsg += "(or '--regexp')"

lib/core/common.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2362,7 +2362,7 @@ def setOptimize():
23622362
#conf.predictOutput = True
23632363
conf.keepAlive = True
23642364
conf.threads = 3 if conf.threads < 3 else conf.threads
2365-
conf.nullConnection = not any([conf.data, conf.textOnly, conf.titles, conf.string, conf.regexp, conf.tor])
2365+
conf.nullConnection = not any([conf.data, conf.textOnly, conf.titles, conf.string, conf.notString, conf.regexp, conf.tor])
23662366

23672367
if not conf.nullConnection:
23682368
debugMsg = "turning off --null-connection switch used indirectly by switch -o"

lib/core/option.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1865,6 +1865,14 @@ def __basicOptionValidation():
18651865
errMsg = "option '--string' is incompatible with switch '--null-connection'"
18661866
raise sqlmapSyntaxException, errMsg
18671867

1868+
if conf.notString and conf.nullConnection:
1869+
errMsg = "option '--not-string' is incompatible with switch '--null-connection'"
1870+
raise sqlmapSyntaxException, errMsg
1871+
1872+
if conf.string and conf.notString:
1873+
errMsg = "option '--string' is incompatible with switch '--not-string'"
1874+
raise sqlmapSyntaxException, errMsg
1875+
18681876
if conf.regexp and conf.nullConnection:
18691877
errMsg = "option '--regexp' is incompatible with switch '--null-connection'"
18701878
raise sqlmapSyntaxException, errMsg

lib/core/optiondict.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
"level": "integer",
7777
"risk": "integer",
7878
"string": "string",
79+
"notString": "notString",
7980
"regexp": "string",
8081
"code": "integer",
8182
"textOnly": "boolean",

lib/parse/cmdline.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,10 @@ def cmdLineParser():
245245
help="String to match when "
246246
"query is evaluated to True")
247247

248+
detection.add_option("--not-string", dest="notString",
249+
help="String to match when "
250+
"query is evaluated to False")
251+
248252
detection.add_option("--regexp", dest="regexp",
249253
help="Regexp to match when "
250254
"query is evaluated to True")

lib/request/comparison.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def comparison(page, headers, code=None, getRatioValue=False, pageLength=None):
3131
return _
3232

3333
def _adjust(condition, getRatioValue):
34-
if not any([conf.string, conf.regexp, conf.code]):
34+
if not any([conf.string, conf.notString, conf.regexp, conf.code]):
3535
# Negative logic approach is used in raw page comparison scheme as that what is "different" than original
3636
# PAYLOAD.WHERE.NEGATIVE response is considered as True; in switch based approach negative logic is not
3737
# applied as that what is by user considered as True is that what is returned by the comparison mechanism
@@ -54,14 +54,18 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
5454
seqMatcher = threadData.seqMatcher
5555
seqMatcher.set_seq1(kb.pageTemplate)
5656

57-
if any([conf.string, conf.regexp]):
57+
if any([conf.string, conf.notString, conf.regexp]):
5858
rawResponse = "%s%s" % (listToStrValue(headers.headers if headers else ""), page)
5959

60-
# String to match in page when the query is valid
60+
# String to match in page when the query is True and/or valid
6161
if conf.string:
6262
return conf.string in rawResponse
6363

64-
# Regular expression to match in page when the query is valid
64+
# String to match in page when the query is False and/or invalid
65+
if conf.notString:
66+
return conf.notString not in rawResponse
67+
68+
# Regular expression to match in page when the query is True and/or valid
6569
if conf.regexp:
6670
return re.search(conf.regexp, rawResponse, re.I | re.M) is not None
6771

sqlmap.conf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,11 @@ risk = 1
247247
# Refer to the user's manual for further details.
248248
string =
249249

250+
# String to match within the raw response when the query is evaluated to
251+
# False, only needed if the page content dynamically changes at each refresh.
252+
# Refer to the user's manual for further details.
253+
notString =
254+
250255
# Regular expression to match within the raw response when the query is
251256
# evaluated to True, only needed if the needed if the page content
252257
# dynamically changes at each refresh.

0 commit comments

Comments
 (0)