Package Peach :: Package Generators :: Module flipper
[hide private]

Source Code for Module Peach.Generators.flipper

  1   
  2  ''' 
  3  Default flippers.  Flippers are used to flip bits in a data.  This 
  4  is used for "random" or "bute force" fuzzing.  Usefull on codecs and 
  5  fully unknown protocols.  Runtime is long for flippers. 
  6   
  7  Flippers can be "stacked" so to speak to make for interesting random 
  8  flipping.  To stack, just use one Flipper as the data generator for 
  9  another flipper. 
 10   
 11  @author: Michael Eddington 
 12  @version: $Id: Peach.Generators.flipper-pysrc.html 1138 2008-08-16 19:39:03Z meddingt $ 
 13  ''' 
 14   
 15  # 
 16  # Copyright (c) 2005-2007 Michael Eddington 
 17  # 
 18  # Permission is hereby granted, free of charge, to any person obtaining a copy  
 19  # of this software and associated documentation files (the "Software"), to deal 
 20  # in the Software without restriction, including without limitation the rights  
 21  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell  
 22  # copies of the Software, and to permit persons to whom the Software is  
 23  # furnished to do so, subject to the following conditions: 
 24  # 
 25  # The above copyright notice and this permission notice shall be included in     
 26  # all copies or substantial portions of the Software. 
 27  # 
 28  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
 29  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  
 30  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  
 31  # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  
 32  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 33  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
 34  # SOFTWARE. 
 35  # 
 36   
 37  # Authors: 
 38  #   Michael Eddington (mike@phed.org) 
 39   
 40  # $Id: Peach.Generators.flipper-pysrc.html 1138 2008-08-16 19:39:03Z meddingt $ 
 41   
 42   
 43  import re, struct 
 44  from Peach.generator import * 
 45   
 46  #__all__ = ["SequentialFlipper"] 
 47   
48 -class SequentialFlipper(SimpleGenerator):
49 ''' 50 Sequencially flipps bits in a data blob. This is for 51 "random" fuzzing. Usefull brute forcing, codecs, etc. 52 ''' 53 54 _data = None 55 _position = 0 56
57 - def __init__(self, group, data):
58 ''' 59 @type data: string 60 @param data: Binary static blob to flip 61 ''' 62 SimpleGenerator.__init__(self, group) 63 64 self._data = str(data) # Could be a unicode string. 65 self._len = len(data) 66 self._position = 0 67 self._bit = 0
68
69 - def next(self):
70 if self._bit == 7: 71 self._position += 1 72 self._bit = 0 73 74 if self._position >= self._len: 75 self._position -= 1 76 self._bit = 7 77 78 raise GeneratorCompleted("all done here") 79 80 else: 81 self._bit += 1
82
83 - def reset(self):
84 self._bit = 0 85 self._position = 0
86
87 - def getRawValue(self):
88 89 if self._position >= self._len: 90 return "" 91 92 data = self._data 93 94 byte = struct.unpack('B', data[self._position])[0] 95 mask = 1 << self._bit 96 97 if ( (byte & mask) >> self._bit ) == 1: 98 99 mask = 0 100 for i in range(8-self._bit): 101 mask |= 1 << i 102 mask = mask << 1 103 104 if self._bit > 1: 105 mask = mask << (self._bit) 106 107 for i in range(self._bit): 108 mask |= 1 << i 109 110 byte = byte & mask 111 112 else: 113 byte = byte | mask 114 115 packedup = struct.pack("B", byte) 116 data = data[:self._position] + packedup + data[self._position+1:] 117 118 return data
119
120 -class SequentialDWORDSlider(SimpleGenerator):
121 ''' 122 Sequencially slides a DWORD through a data blob. This is for 123 "random" fuzzing. Usefull brute forcing, codecs, etc. 124 ''' 125 126 _data = None 127 _position = 0 128
129 - def __init__(self, group, data, dword=0xFFFFFFFF):
130 ''' 131 @type data: string 132 @param data: Binary static blob to slide through 133 @type dword: ulong 134 @param dword: The dword to slide through (e.g. 0xBAADFOOD), slides 0XFFFFFFFF by default 135 ''' 136 SimpleGenerator.__init__(self, group) 137 138 self._data = str(data) # Could be a unicode string. 139 self._len = len(data) 140 self._position = 0 141 self._dword = dword 142 self._counts = 0
143
144 - def next(self):
145 146 if self._counts < 4 and self._counts < self._len: 147 self._counts += 1 148 elif self._position < self._len: 149 self._position += 1 150 else: 151 raise GeneratorCompleted("DWORD Slider Complete")
152
153 - def reset(self):
154 self._position = 0
155
156 - def getRawValue(self):
157 158 if self._position >= self._len: 159 return "" 160 161 data = self._data 162 163 inject = '' 164 remaining = self._len - self._position 165 166 #Need to determine the size of what to inject based on 167 #the end of the data and the beginning 168 if self._counts == 0 or remaining == 1: 169 inject = struct.pack('B', self._dword & 0x000000FF) 170 elif (self._counts == 1 and remaining >= 2) or remaining <= 2: 171 inject = struct.pack('H', self._dword & 0x0000FFFF) #ushort 172 elif (self._counts == 2 and remaining >= 3) or remaining <= 3: 173 inject = struct.pack('B', (self._dword & 0x00FF0000) >> 16) + \ 174 struct.pack('>H', self._dword & 0xFFFF) 175 else: 176 inject = struct.pack('L', self._dword) 177 178 data = data[:self._position] + inject + data[self._position + len(inject):] 179 180 return data
181 182 183 import random
184 -class PartialFlipper(SimpleGenerator):
185 ''' 186 Performs flips of 20% of bits in data. 187 ''' 188 189 _data = None 190 _position = 0 191
192 - def __init__(self, group, data, maxRounds = None):
193 ''' 194 @type data: string 195 @param data: Binary static blob to flip 196 @type maxRounds: int 197 @param maxRounds: optional, override 0.2% with a fixed number 198 ''' 199 SimpleGenerator.__init__(self, group) 200 201 self._data = str(data) # Could be a unicode string. 202 self._len = len(data) 203 self._position = 0 204 self._bit = 0 205 self._maxRounds = int((len(data)*8) * 0.20) 206 self._round = 0 207 208 if maxRounds != None: 209 self._maxRounds = maxRounds
210 211
212 - def next(self):
213 self._round += 1 214 215 if self._round > self._maxRounds: 216 raise GeneratorCompleted("all don here") 217 218 self._position = random.randint(0, len(self._data)-1) 219 self._bit = random.randint(0, 7)
220
221 - def reset(self):
222 self._bit = 0 223 self._position = 0 224 self._round = 0
225
226 - def getRawValue(self):
227 228 if self._position >= self._len: 229 return "" 230 231 data = self._data 232 233 byte = struct.unpack('B', data[self._position])[0] 234 mask = 1 << self._bit 235 236 if ( (byte & mask) >> self._bit ) == 1: 237 238 mask = 0 239 for i in range(8-self._bit): 240 mask |= 1 << i 241 mask = mask << 1 242 243 if self._bit > 1: 244 mask = mask << (self._bit) 245 246 for i in range(self._bit): 247 mask |= 1 << i 248 249 byte = byte & mask 250 251 else: 252 byte = byte | mask 253 254 packedup = struct.pack("B", byte) 255 data = data[:self._position] + packedup + data[self._position+1:] 256 257 return data
258 259 # end 260