./others/rCFuzz.py

0.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
##################################################################################
#
# rCfuzz.py v0.1 (c) 2008
# dB [at] rawsecurity.org
#
# Command line arguments fuzzer used for finding local vulnerabilities 
# in setuid/setgid binaries.  
#
# Usuage: rawCmdFuzz.py "program -a NUM -b SYM" [-s=5] [-p=0.1] [-m=900] [-i=50]
#
# Fuzz Data Types
# RAN - Generates a random string with all characters except special 
#       UNIX characters.
# SYM - Uses only random symbols.
# NUM - Generates a random number.
# FRM - Uses format string %n or %s.
# STR - Generates a random string using alphanumeric characters.
#
# Optional params
# -s Random seed
# -p Pause in seconds
# -m Max length of fuzz strings
# -i Increment value
#
##################################################################################
 
import signal
import os
import string
import time
import sys
import random
import commands
 
fuzzTypes = ["RAN","SYM","NUM","FRM","STR"]
symbols = ["!","$","%","*","+",",","-",".","/",
		   ":","?","@","^","_"]
formats = ["%s","%x","%n"]
 
INDEX = 0
STR_INDEX = 1
PARAM = 2
COUNT = 3
 
def getOneChar():
	ascii = 65
	if random.randint(0,1) == 1:
		ascii = random.randint(65,90)
	else:
		ascii = random.randint(97,122)
	return chr(ascii)
 
def getOneSymbol():
	global symbols
	return symbols[random.randint(0,len(symbols)-1)]
 
def getRandomString(length):
	str_list = []
	ascii = 65
	for i in range(0,length):
		str_list.append(getOneChar())
	return ''.join(str_list)
 
def getRandomNumber(length):
	num_list = []
	for i in range(0,length):
		num_list.append(str(random.randint(0,9)))
	return ''.join(num_list)
 
def getRandomFormat(length):
	frmt_list = []
	for i in range(0,length):
		frmt_list.append(formats[random.randint(0,len(formats)-1)])
	return ''.join(frmt_list)
 
def getRandomSymbol(length):
	sym_list = []
	for i in range(0,length):
		sym_list.append(getOneSymbol())
	return ''.join(sym_list)
 
def getRandomRandom(length):
	randStr = ""
	randChar = ""
	for i in range(0,length):
		if random.randint(0,1) == 1:
			randChar = getOneChar()
		else:
			randChar = getOneSymbol()
		randStr += randChar
	return randStr
 
def doneFuzzing(params,maxLength):
	for i in range(0,len(params)):
		if params[i][STR_INDEX] != -1 and params[i][COUNT] < maxLength:
			return False
	return True
 
def printInfo(lastCmd,params):
	print "Last call: " + lastCmd
	for i in range(0,len(params)):
		index = str(params[i][INDEX])
		param = str(params[i][PARAM])
		count = str(params[i][COUNT])
		print "Index: " + index + " Param: " + param + " Num: " + count
	print ""
 
print ""
print "   rCfuzz v0.1 [ Command line fuzzer ]"
print "   dB [at] rawsecurity.org"
print ""
 
seed = 1
pause = 0.0
maxLength = 600
increment = 25
 
if len(sys.argv) < 2:
	print 'Usuage: rawCmdFuzz.py "program arg1 arg2 ..." [-s=5] [-p=0.1]\n'
	sys.exit(-1)
 
if len(sys.argv) > 2:
	for i in range(2,len(sys.argv)):
		if sys.argv[i].startswith("-s="):
			seed = int(sys.argv[i][3:])
		elif sys.argv[i].startswith("-p="):
			pause = float(sys.argv[i][3:])
		elif sys.argv[i].startswith("-m="):
			maxLength = int(sys.argv[i][3:])
		elif sys.argv[i].startswith("-i="):
			increment = int(sys.argv[i][3:])
 
random.seed(seed)
 
# Extract target process
cmdPieces = sys.argv[1].split(" ")
target = cmdPieces[0]
 
# Build list of parameters
paramList = []
for i in range(1,len(cmdPieces)):
	index = 0
	try:
		param = string.upper(cmdPieces[i])
		index = fuzzTypes.index(param)
	except ValueError:
	# Not a fuzz data type, must be static parameter
		index = -1
	paramList.append([i,index,cmdPieces[i],1])
 
time.sleep(3)
 
try:
	while doneFuzzing(paramList,maxLength) == False:
		# Build execute string
		cmdExec = target
		for i in range(0,len(paramList)):
			# Add a space
			cmdExec += " "
 
			if paramList[i][STR_INDEX] == -1:
			# Static parameter
				cmdExec += paramList[i][PARAM]
			else:
			# Fuzz type
				paramType = string.upper(paramList[i][PARAM])
				currLength = paramList[i][COUNT]
				if paramType == "STR":
					cmdExec += paramType.replace("STR",getRandomString(currLength))
				elif paramType == "NUM":
					cmdExec += paramType.replace("NUM",getRandomNumber(currLength))
				elif paramType == "FRM":
					cmdExec += paramType.replace("FRM",getRandomFormat(currLength))
				elif paramType == "SYM":
					cmdExec += paramType.replace("SYM",getRandomSymbol(currLength))
				elif paramType == "RAN":
					cmdExec += paramType.replace("RAN",getRandomRandom(currLength))
 
		print "Calling: " + cmdExec
		status = os.WTERMSIG(os.system(cmdExec))
 
		if status == signal.SIGSEGV or status == signal.SIGILL or status == signal.SIGABRT:
			print "\nTarget process has crashed."
			printInfo(cmdExec,paramList)
			sys.exit(0)
 
		# Increment first param count
		# Goes through every permutation
		done = False
		for i in range(0,len(paramList)):
			if paramList[i][STR_INDEX] != -1:
				done = False
				paramList[i][COUNT] += increment
				if paramList[i][COUNT] > maxLength:
					paramList[i][COUNT] = 1
					done = True
				else:
					break
		if done == True:
			break
		time.sleep(pause)
 
	print "Target process did not crash\n"
 
except KeyboardInterrupt:
	print "\nAborting..."
	printInfo(cmdExec,paramList)
	sys.exit(0)

Back