Package Peach :: Package Transformers :: Module encode
[hide private]

Source Code for Module Peach.Transformers.encode

  1   
  2  ''' 
  3  Encoding transforms (URL, Base64, etc). 
  4   
  5  @author: Michael Eddington 
  6  @version: $Id: Peach.Transformers.encode-pysrc.html 1138 2008-08-16 19:39:03Z meddingt $ 
  7  ''' 
  8   
  9  # 
 10  # Copyright (c) 2005-2008 Michael Eddington 
 11  # Copyright (c) 2004-2005 IOActive Inc. 
 12  # 
 13  # Permission is hereby granted, free of charge, to any person obtaining a copy  
 14  # of this software and associated documentation files (the "Software"), to deal 
 15  # in the Software without restriction, including without limitation the rights  
 16  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell  
 17  # copies of the Software, and to permit persons to whom the Software is  
 18  # furnished to do so, subject to the following conditions: 
 19  # 
 20  # The above copyright notice and this permission notice shall be included in     
 21  # all copies or substantial portions of the Software. 
 22  # 
 23  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
 24  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  
 25  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  
 26  # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  
 27  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 28  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
 29  # SOFTWARE. 
 30  # 
 31   
 32  # Authors: 
 33  #   Michael Eddington (mike@phed.org) 
 34   
 35  # $Id: Peach.Transformers.encode-pysrc.html 1138 2008-08-16 19:39:03Z meddingt $ 
 36   
 37   
 38  import urllib 
 39  import xml.sax.saxutils 
 40  import base64 
 41  from struct import * 
 42  from Peach.transformer import Transformer 
 43   
 44   
45 -class SidStringToBytes(Transformer):
46 ''' 47 Convert a string representation SID to a bytes. 48 49 Format: S-1-5-21-2127521184-1604012920-1887927527-1712781 50 ''' 51
52 - def realEncode(self, data):
53 sid = data.split('-') 54 55 if len(sid) < 3 or sid[0] != 'S': 56 raise Exception("Invalid SID string: %s" % data) 57 58 ret = pack("BBBBBBBB", int(sid[1]), int(sid[2]), 0,0,0,0,0,5) 59 60 for i in range(int(sid[2])): 61 ret += pack("I", int(sid[i+3])) 62 63 return ret
64 65
66 -class WideChar(Transformer):
67 ''' 68 Make a normal string a wchar string. Note, does not convert unicode strings 69 into wchar strings or anything super fancy. 70 ''' 71
72 - def realEncode(self, data):
73 try: 74 return data.encode("utf-16le") 75 except: 76 pass 77 78 # The lame way... 79 ret = "" 80 for c in data: 81 ret += c + "\0" 82 83 return ret
84
85 - def realDecode(self, data):
86 try: 87 return str(data.decode("utf-16le")) 88 except: 89 pass 90 91 # Do it the lame way 92 ret = "" 93 for i in range(0, len(data), 2): 94 ret += data[i] 95 96 return ret
97 98
99 -class UrlEncode(Transformer):
100 ''' 101 URL encode w/o pluses. 102 ''' 103
104 - def realEncode(self, data):
105 return urllib.quote(data)
106
107 - def realDecode(self, data):
108 return urllib.unquote(data)
109 110
111 -class NetBiosDecode(Transformer):
112 ''' 113 NetBiosName Decode 114 115 @author: Blake Frantz 116 ''' 117
118 - def __init__(self, anotherTransformer = None):
119 ''' 120 Create Transformer object. 121 122 @type anotherTransformer: Transformer 123 @param anotherTransformer: A transformer to run next 124 125 ''' 126 Transformer.__init__(self, anotherTransformer)
127
128 - def realEncode(self, data):
129 130 if data % 2 != 0: 131 raise("Invalid NetBiosEncoding -- length must be divisible by two") 132 133 decoded = "" 134 data = data.upper() 135 136 # loop through each byte 137 for cnt in range(0, len(data), 2): 138 139 c1 = ord(data[cnt]) 140 c2 = ord(data[cnt+1]) 141 142 part1 = (c1 - 0x41) * 16 143 part2 = (c2 - 0x41) 144 145 decoded += chr(part1 + part2) 146 147 return decoded
148
149 - def realDecode(self, data):
150 151 encoded = "" 152 153 data = data.upper() 154 155 if self._pad: 156 while len(data) < 16: 157 data += " " 158 159 data = data[:16] 160 161 # loop through each byte 162 for c in data: 163 164 # grab the ascii value of it 165 ascii = ord(c) 166 167 encoded += chr((ascii / 16) + 0x41) 168 encoded += chr((ascii - (ascii/16 * 16) + 0x41)) 169 170 # the 16th byte is the name scope id, set it to 'host' 171 # and null term it 172 if self._pad: 173 encoded = encoded[:30] 174 encoded += '\x41' 175 encoded += '\x41' 176 177 return encoded 178 179
180 -class NetBiosEncode(Transformer):
181 ''' 182 NetBiosName Encoded 183 184 @author: Blake Frantz 185 ''' 186
187 - def __init__(self, anotherTransformer = None, pad = True):
188 ''' 189 Create Transformer object. 190 191 @type anotherTransformer: Transformer 192 @param anotherTransformer: A transformer to run next 193 @type pad: Boolean 194 @param pad: Will pad / trim encoded name to 32 bytes 195 ''' 196 Transformer.__init__(self, anotherTransformer) 197 self._pad = pad
198
199 - def realEncode(self, data):
200 201 encoded = "" 202 203 data = data.upper() 204 205 if self._pad: 206 while len(data) < 16: 207 data += " " 208 209 data = data[:16] 210 211 # loop through each byte 212 for c in data: 213 214 # grab the ascii value of it 215 ascii = ord(c) 216 217 encoded += chr((ascii / 16) + 0x41) 218 encoded += chr((ascii - (ascii/16 * 16) + 0x41)) 219 220 # the 16th byte is the name scope id, set it to 'host' 221 # and null term it 222 if self._pad: 223 encoded = encoded[:30] 224 encoded += '\x41' 225 encoded += '\x41' 226 227 return encoded
228
229 - def realDecode(self, data):
230 231 if data % 2 != 0: 232 raise("Invalid NetBiosEncoding -- length must be divisible by two") 233 234 decoded = "" 235 data = data.upper() 236 237 # loop through each byte 238 for cnt in range(0, len(data), 2): 239 240 c1 = ord(data[cnt]) 241 c2 = ord(data[cnt+1]) 242 243 part1 = (c1 - 0x41) * 16 244 part2 = (c2 - 0x41) 245 246 decoded += chr(part1 + part2) 247 248 return decoded 249 250
251 -class UrlEncodePlus(Transformer):
252 ''' 253 URL encode with spaces turned to pluses 254 ''' 255
256 - def realEncode(self, data):
257 return urllib.quote_plus(data)
258
259 - def realDecode(self, data):
260 return urllib.unquote_plus(data)
261 262 263
264 -class Base64Encode(Transformer):
265 ''' 266 Base64 encode. 267 '''
268 - def realEncode(self, data):
269 return base64.encodestring(data).rstrip().replace('\n', '')
270 - def realDecode(self, data):
271 return base64.decodestring(data)
272
273 -class Base64Decode(Transformer):
274 ''' 275 Base64 decode. 276 '''
277 - def realEncode(self, data):
278 return base64.decodestring(data)
279 - def realDecode(self, data):
280 return base64.encodestring(data).rstrip().replace('\n', '')
281 282
283 -def _HtmlEncode(strInput, default=''):
284 285 if strInput == None or len(strInput) == 0: 286 strInput = default 287 288 if strInput == None or len(strInput) == 0: 289 return '' 290 291 # Allow: a-z A-Z 0-9 SPACE , . 292 # Allow (dec): 97-122 65-90 48-57 32 44 46 293 294 out = '' 295 for char in strInput: 296 c = ord(char) 297 if ((c >= 97 and c <= 122) or 298 (c >= 65 and c <= 90 ) or 299 (c >= 48 and c <= 57 ) or 300 c == 32 or c == 44 or c == 46): 301 out += char 302 else: 303 out += "&#%d;" % c 304 305 return out
306
307 -class HtmlEncodeAgressive(Transformer):
308 ''' 309 Perform agressive HTML encoding. Only alphanum's will not 310 be encoded. 311 ''' 312
313 - def realEncode(self, data):
314 return _HtmlEncode(data)
315
316 - def unittest():
317 t = HtmlEncodeAgressive() 318 print "HtmlEncode: [" + t.realEncode("<script> alert('meow') </script>") + "]"
319 unittest = staticmethod(unittest)
320 321
322 -class HtmlEncode(Transformer):
323 ''' 324 Perform standard HTML encoding of < > & and " 325 ''' 326
327 - def realEncode(self, data):
328 return xml.sax.saxutils.quoteattr(data).strip('"')
329
330 - def realDecode(self, data):
331 return xml.sax.saxutils.unescape(data)
332
333 -class JsEncode(Transformer):
334 ''' 335 Perform JavaScript encoding of a string" 336 ''' 337
338 - def realEncode(self, strInput):
339 if strInput == None or len(strInput) == 0: 340 return "" 341 342 # Allow: a-z A-Z 0-9 SPACE , . 343 # Allow (dec): 97-122 65-90 48-57 32 44 46 344 345 out = '' 346 for char in strInput: 347 c = ord(char) 348 if ((c >= 97 and c <= 122) or 349 (c >= 65 and c <= 90 ) or 350 (c >= 48 and c <= 57 ) or 351 c == 32 or c == 44 or c == 46): 352 out += char 353 elif c <= 127: 354 out += "\\x%02X" % c 355 else: 356 out += "\\u%04X" % c 357 358 return out
359
360 -class HtmlDecode(Transformer):
361 ''' 362 Decode HTML encoded string 363 ''' 364
365 - def realEncode(self, data):
366 return xml.sax.saxutils.unescape(data)
367
368 - def realEncode(self, data):
369 return xml.sax.saxutils.escape(data)
370 371
372 -class Utf8(Transformer):
373 ''' 374 Encode string as UTF-8. 375 ''' 376
377 - def realEncode(self, data):
378 return data.encode("utf8")
379
380 - def realDecode(self, data):
381 return str(data.decode("utf8"))
382 383
384 -class Utf16(Transformer):
385 ''' 386 Encode string as UTF-16. String is prefixed with BOM. 387 Supports surrogate pair encoding of values larger then 0xFFFF. 388 ''' 389
390 - def realEncode(self, data):
391 return data.encode("utf16")
392
393 - def realDecode(self, data):
394 return str(data.decode("utf16"))
395 396
397 -class Utf16Le(Transformer):
398 ''' 399 Encode string as UTF-16LE. Supports surrogate pair 400 encoding of values larger then 0xFFFF. 401 ''' 402
403 - def realEncode(self, data):
404 ret = '' 405 406 for c in data: 407 if ord(c) <= 0xFF: 408 return pack("<BB", 0x00, ord(c)) 409 elif ord(c) <= 0xFFFF: 410 return pack("<H", ord(c)) 411 elif ord(c) > 0xFFFF: 412 # Perform surrogate pair encoding 413 value = ord(c) # value 414 value -= 0x10000 415 valueHigh = value & 0xFFF # high bits 416 valueLow = value & 0xFFF000 # low bits 417 word1 = 0xD800 418 word2 = 0xDC00 419 word1 = word1 | valueHigh 420 word2 = word2 | valueLow 421 return pack("<HH", word1, word2) 422 return ret
423
424 -class Utf16Be(Transformer):
425 ''' 426 Encode string as UTF-16BE. Supports surrogate pair 427 encoding of values larger then 0xFFFF. 428 ''' 429
430 - def realEncode(self, data):
431 ret = '' 432 433 for c in data: 434 if ord(c) <= 0xFF: 435 return pack(">BB", 0x00, ord(c)) 436 elif ord(c) <= 0xFFFF: 437 return pack(">H", ord(c)) 438 elif ord(c) > 0xFFFF: 439 # Perform surrogate pair encoding 440 value = ord(c) # value 441 value -= 0x10000 442 valueHigh = value & 0xFFF # high bits 443 valueLow = value & 0xFFF000 # low bits 444 word1 = 0xD800 445 word2 = 0xDC00 446 word1 = word1 | valueHigh 447 word2 = word2 | valueLow 448 return pack("<HH", word1, word2) 449 return ret
450 451
452 -class Ipv4StringToOctet(Transformer):
453 ''' 454 Convert a dot notiation ipv4 address into a 4 byte 455 octect representation. 456 ''' 457
458 - def realEncode(self, data):
459 data = data.split('.') 460 for i in range(len(data)): 461 data[i] = int(data[i]) 462 463 return pack('BBBB', data[0], data[1], data[2], data[3])
464
465 -class Ipv4StringToNetworkOctet(Transformer):
466 ''' 467 Convert a dot notiation ipv4 address into a 4 byte 468 octect representation. 469 ''' 470
471 - def realEncode(self, data):
472 data = data.split('.') 473 for i in range(len(data)): 474 try: 475 data[i] = int(data[i]) 476 except: 477 data[i] = 0 478 479 for i in range(len(data), 4): 480 data.append(0) 481 482 return pack('!BBBB', data[0], data[1], data[2], data[3])
483 484
485 -class Ipv6StringToOctet(Transformer):
486 ''' 487 Convert a collen notiation ipv6 address into a 4 byte 488 octect representation. 489 ''' 490
491 - def realEncode(self, data):
492 return pack('BBBBBBBBBBBBBBBB',data.split(':'))
493 494
495 -class Hex(Transformer):
496 ''' 497 Transform a number to hex w/o prefix. 498 '''
499 - def realEncode(self, data):
500 try: 501 return hex(int(data))[2:] 502 except: 503 return data
504 505 506
507 -class HexString(Transformer):
508 ''' 509 Transforms a string of bytes into the specified Hex format. 510 511 Example: 512 513 >>> gen = Static("AAAABBBB").setTransformer(HexString()) 514 >>> print gen.getValue() 515 41 41 41 41 42 42 42 42 516 >>> gen = Static("AAAABBBB").setTransformer(HexString(None, 4, "0x")) 517 >>> print gen.getValue() 518 0x414141410x42424242 519 >>> gen = Static("AAAABBBB").setTransformer(HexString(None, 1, " \\x")) 520 >>> print gen.getValue() 521 \x41 \x41 \x41 \x41 \x42 \x42 \x42 \x42 522 >>> 523 ''' 524
525 - def __init__(self, anotherTransformer = None, resolution = None, prefix = None):
526 ''' 527 Create Transformer object. 528 529 @type anotherTransformer: Transformer 530 @param anotherTransformer: A transformer to run next 531 @type resolution: Int 532 @param resolution: Number of nibbles between separator (Must be a postive even integer) 533 @type prefix: String 534 @param prefix: A value to prepend each chunk with (defaults to ' ') 535 ''' 536 537 Transformer.__init__(self, anotherTransformer) 538 self._resolution = resolution 539 self._prefix = prefix
540
541 - def realEncode(self, data):
542 ret = '' 543 544 if self._resolution == None: 545 self._resolution = 1 546 547 # try to detect if user passed in odd numbered value 548 if self._resolution % 2 and self._resolution != 1: 549 raise Exception("Resolution must be 1 or a multiple of two") 550 551 if len(data) % self._resolution != 0: 552 raise Exception("Data length must be divisible by resolution") 553 554 if self._prefix == None: 555 self._prefix = " " 556 557 tmp = '' 558 559 for c in data: 560 h = hex(ord(c))[2:] 561 562 if len(h) == 2: 563 tmp += h 564 else: 565 tmp += "0%s" % h 566 567 if len(tmp) / 2 == self._resolution: 568 ret += self._prefix + tmp 569 tmp = '' 570 571 ret = ret.strip() 572 573 return ret
574 575 # end 576