Skip to content

Commit 3f3442e

Browse files
authored
Merge pull request #69 from cotonne/master
WIP: Command-line support for NoSQLMap/nsmweb
2 parents a79ce46 + d351d14 commit 3f3442e

File tree

5 files changed

+211
-110
lines changed

5 files changed

+211
-110
lines changed

nosqlmap.py

+82-14
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
import signal
1313
import ast
1414

15+
import argparse
1516

16-
def main():
17+
18+
def main(args):
1719
signal.signal(signal.SIGINT, signal_handler)
1820
global optionSet
1921
# Set a list so we can track whether options are set or not to avoid resetting them in subsequent calls to the options menu.
@@ -38,7 +40,10 @@ def main():
3840
dbPort = 27017
3941
myIP = "Not Set"
4042
myPort = "Not Set"
41-
mainMenu()
43+
if args.attack:
44+
attack(args)
45+
else:
46+
mainMenu()
4247

4348
def mainMenu():
4449
global platform
@@ -56,11 +61,11 @@ def mainMenu():
5661
mmSelect = True
5762
while mmSelect:
5863
os.system('clear')
59-
print " _ _ ___ ___ _ __ __           "
60-
print "| \| |___/ __|/ _ \| | | \/ |__ _ _ __ "
64+
print " _ _ ___ ___ _ __ __ "
65+
print "| \| |___/ __|/ _ \| | | \/ |__ _ _ __ "
6166
print "| .` / _ \__ \ (_) | |__| |\/| / _` | '_ \\"
6267
print("|_|\_\___/___/\__\_\____|_| |_\__,_| .__/")
63-
print(" v0.7 codingo@protonmail.com      |_|   ")
68+
print(" v0.7 codingo@protonmail.com |_| ")
6469
print "\n"
6570
print "1-Set options"
6671
print "2-NoSQL DB Access Attacks"
@@ -116,6 +121,50 @@ def mainMenu():
116121
else:
117122
raw_input("Invalid selection. Press enter to continue.")
118123

124+
def build_request_headers(reqHeadersIn):
125+
requestHeaders = {}
126+
reqHeadersArray = reqHeadersIn.split(",")
127+
headerNames = reqHeadersArray[0::2]
128+
headerValues = reqHeadersArray[1::2]
129+
requestHeaders = dict(zip(headerNames, headerValues))
130+
return requestHeaders
131+
132+
def build_post_data(postDataIn):
133+
pdArray = postDataIn.split(",")
134+
paramNames = pdArray[0::2]
135+
paramValues = pdArray[1::2]
136+
postData = dict(zip(paramNames,paramValues))
137+
return postData
138+
139+
def attack(args):
140+
platform = args.platform
141+
victim = args.victim
142+
webPort = args.webPort
143+
dbPort = args.dbPort
144+
myIP = args.myIP
145+
myPort = args.myPort
146+
uri = args.uri
147+
https = args.https
148+
verb = args.verb
149+
httpMethod = args.httpMethod
150+
requestHeaders = build_request_headers(args.requestHeaders)
151+
postData = build_post_data(args.postData)
152+
153+
if args.attack == 1:
154+
if platform == "MongoDB":
155+
nsmmongo.netAttacks(victim, dbPort, myIP, myPort, args)
156+
elif platform == "CouchDB":
157+
nsmcouch.netAttacks(victim, dbPort, myIP, args)
158+
elif args.attack == 2:
159+
if httpMethod == "GET":
160+
nsmweb.getApps(webPort,victim,uri,https,verb,requestHeaders, args)
161+
elif httpMethod == "POST":
162+
nsmweb.postApps(victim,webPort,uri,https,verb,postData,requestHeaders, args)
163+
elif args.attack == 3:
164+
scanResult = nsmscan.massScan(platform)
165+
if scanResult != None:
166+
optionSet[0] = True
167+
victim = scanResult[1]
119168

120169
def platSel():
121170
global platform
@@ -288,10 +337,7 @@ def options():
288337
print "POST request set"
289338
optionSet[3] = True
290339
postDataIn = raw_input("Enter POST data in a comma separated list (i.e. param name 1,value1,param name 2,value2)\n")
291-
pdArray = postDataIn.split(",")
292-
paramNames = pdArray[0::2]
293-
paramValues = pdArray[1::2]
294-
postData = dict(zip(paramNames,paramValues))
340+
build_post_data(postDataIn)
295341
httpMethod = "POST"
296342

297343
else:
@@ -448,19 +494,41 @@ def options():
448494

449495
elif select == "h":
450496
reqHeadersIn = raw_input("Enter HTTP Request Header data in a comma separated list (i.e. header name 1,value1,header name 2,value2)\n")
451-
reqHeadersArray = reqHeadersIn.split(",")
452-
headerNames = reqHeadersArray[0::2]
453-
headerValues = reqHeadersArray[1::2]
454-
requestHeaders = dict(zip(headerNames, headerValues))
497+
build_request_headers(reqHeadersIn)
455498

456499
elif select == "x":
457500
return
458501

502+
def build_parser():
503+
parser = argparse.ArgumentParser()
504+
parser.add_argument("--attack", help="1 = NoSQL DB Access Attacks, 2 = NoSQL Web App attacks, 3 - Scan for Anonymous platform Access", type=int, choices=[1,2,3])
505+
parser.add_argument("--platform", help="Platform to attack", choices=["MongoDB", "CouchDB"], default="MongoDB")
506+
parser.add_argument("--victim", help="Set target host/IP (ex: localhost or 127.0.0.1)")
507+
parser.add_argument("--dbPort", help="Set shell listener port", type=int)
508+
parser.add_argument("--myIP",help="Set my local platform/Shell IP")
509+
parser.add_argument("--myPort",help="Set my local platform/Shell port", type=int)
510+
parser.add_argument("--webPort", help="Set web app port ([1 - 65535])", type=int)
511+
parser.add_argument("--uri", help="Set App Path. For example '/a-path/'. Final URI will be [https option]://[victim option]:[webPort option]/[uri option]")
512+
parser.add_argument("--httpMethod", help="Set HTTP Request Method", choices=["GET","POST"], default="GET")
513+
parser.add_argument("--https", help="Toggle HTTPS", choices=["ON", "OFF"], default="OFF")
514+
parser.add_argument("--verb", help="Toggle Verbose Mode", choices=["ON", "OFF"], default="OFF")
515+
parser.add_argument("--postData", help="Enter POST data in a comma separated list (i.e. param name 1,value1,param name 2,value2)", default="")
516+
parser.add_argument("--requestHeaders", help="Request headers in a comma separated list (i.e. param name 1,value1,param name 2,value2)", default="")
517+
518+
modules = [nsmcouch, nsmmongo, nsmscan, nsmweb]
519+
for module in modules:
520+
group = parser.add_argument_group(module.__name__)
521+
for arg in module.args():
522+
group.add_argument(arg[0], help=arg[1])
523+
524+
return parser
459525

460526
def signal_handler(signal, frame):
461527
print "\n"
462528
print "CTRL+C detected. Exiting."
463529
sys.exit()
464530

465531
if __name__ == '__main__':
466-
main()
532+
parser = build_parser()
533+
args = parser.parse_args()
534+
main(args)

nsmcouch.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
yes_tag = ['y', 'Y']
2222
no_tag = ['n', 'N']
2323

24+
def args():
25+
return []
2426

2527
def couchScan(target,port,pingIt):
2628
if pingIt == True:
@@ -63,8 +65,7 @@ def couchScan(target,port,pingIt):
6365
except:
6466
return [3,None]
6567

66-
67-
def netAttacks(target,port, myIP):
68+
def netAttacks(target,port, myIP, args = None):
6869
print "DB Access attacks (CouchDB)"
6970
print "======================"
7071
mgtOpen = False

nsmmongo.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
yes_tag = ['y', 'Y']
1919
no_tag = ['n', 'N']
2020

21+
def args():
22+
return []
2123

22-
def netAttacks(target, dbPort, myIP, myPort):
24+
def netAttacks(target, dbPort, myIP, myPort, args = None):
2325
print "DB Access attacks (MongoDB)"
2426
print "================="
2527
mgtOpen = False

nsmscan.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
import nsmmongo
88
import nsmcouch
99

10+
def args():
11+
return []
1012

11-
def massScan(platform):
13+
def massScan(platform, args = None):
1214
yes_tag = ['y', 'Y']
1315
no_tag = ['n', 'N']
1416
optCheck = True

0 commit comments

Comments
 (0)