Guest User

feliam

a guest
Jan 13th, 2010
1,107
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ## UNFINISHED -UNFINISHED -UNFINISHED -UNFINISHED -UNFINISHED -UNFINISHED -UNFINISHED -UNFINISHED -
  2. ## This is a preliminary version, lots of tricks are still to be implemented...
  3. ## Anyway if you find some trick not coded here, let me know!
  4. ## Let me implement some of the ways...
  5. ## http://feliam.wordpress.com
  6.  
  7. ## Ref: Some of this was first pointed out in ...  
  8. ##      http://blog.didierstevens.com/2008/04/29/pdf-let-me-count-the-ways/
  9.  
  10.  
  11. import random
  12.  
  13. decoys=[
  14. '''<</Type /Catalog /Pages 2 0 R >>'''
  15. '''<</Count 1 /Kids [3 0 R] /Type /Pages >>'''
  16. '''<</Parent 2 0 R /MediaBox [0 0 595 894] /ProcSet [/PDF /Text] /Resources <</Font <</F1 <</BaseFont /Times-Roman /Subtype /Type1 /Name /F1 /Encoding /WinAnsiEncoding >> >> >> /Type /Page /Contents 4 0 R >>'''
  17. '''4 0 obj'''
  18. '''endstream'''
  19. '''endobj'''
  20. '''xref'''
  21. '''0000000339 00000 n '''
  22. '''trailer'''
  23. '''<</Root 1 0 R /Size 5 >>'''
  24. '''startxref'''
  25. ]
  26. delimiters = list('()<>[]{}/%')
  27. whitespaces = list('\x20\x0a\x0c\x0d')
  28. EOL = '\x0A'
  29.  
  30. def putSome(l):
  31.     some = ""
  32.     size = random.randint(0,5)
  33.     for i in range(0,size):
  34.         some += random.choice(l)
  35.     return some
  36.  
  37. def getSeparator():
  38.     if random.randint(0,100)<40:
  39.         return random.choice([" ","\t"])
  40.     elif random.randint(0,100)<101:
  41.         return "%"+random.choice(decoys)+EOL
  42.  
  43. import struct
  44.  
  45. #For constructing a minimal pdf file
  46. class PDFObject:
  47.     def __init__(self):
  48.         self.n=None
  49.         self.v=None
  50.  
  51.     def __str__(self):
  52.         raise "Fail"
  53.  
  54. class PDFDict(PDFObject):
  55.     def __init__(self, d={}):
  56.         PDFObject.__init__(self)
  57.         self.dict = {}
  58.         for k in d:
  59.             self.dict[k]=d[k]
  60.  
  61.     def add(self,name,obj):
  62.         self.dict[name] = obj
  63.  
  64.     def __str__(self):
  65.         s="<<"
  66.         s+=getSeparator()
  67.         for name in self.dict:
  68.             s+="%s"%PDFName(name).__str__()
  69.             s+=getSeparator()
  70.             s+="%s"%self.dict[name]
  71.             s+=getSeparator()
  72.         s+=">>"
  73.         s+=getSeparator()
  74.         return s
  75.  
  76. class PDFStream(PDFDict):
  77.     def __init__(self,stream=""):
  78.         PDFDict.__init__(self)
  79.         self.stream=stream
  80.         self.filtered=self.stream
  81.         self.filters = []
  82.  
  83.     def appendFilter(self, filter):
  84.         self.filters.append(filter)
  85.         self._applyFilters() #yeah every time .. so what!
  86.  
  87.     def _applyFilters(self):
  88.         self.filtered = self.stream
  89.         for f in self.filters:
  90.                 self.filtered = f.encode(self.filtered)
  91.         self.add('Length', len(self.filtered))
  92.         if len(self.filters)>0:
  93.             self.add('Filter', PDFArray([f.name for f in self.filters]))
  94.         #Add Filter parameters ?
  95.  
  96.     def __str__(self):
  97.         self._applyFilters() #yeah every time .. so what!
  98.         s=""
  99.         s+=PDFDict.__str__(self)
  100.         s+="\nstream\n"
  101.         s+=self.filtered
  102.         s+="\nendstream"
  103.         return s
  104.  
  105. class PDFArray(PDFObject):
  106.     def __init__(self,s):
  107.         PDFObject.__init__(self)
  108.         self.s=s
  109.     def __str__(self):
  110.         return "[%s]"%(random.choice(whitespaces).join([ o.__str__() for o in self.s]))
  111.  
  112.  
  113. ##7.3.5 Name Objects
  114. class PDFName(PDFObject):
  115.     def __init__(self,s):
  116.         PDFObject.__init__(self)
  117.         self.s=s
  118.     def __str__(self):
  119.         obfuscated = ""
  120.         for c in self.s:
  121.             r=random.randint(0,100)
  122.             if (ord(c)<=ord('!') and ord(c) >= ord('~')) or r < 50:
  123.                 obfuscated+='#%02x'%ord(c)
  124.             else:
  125.                 obfuscated+=c
  126.         return "/%s"%obfuscated
  127.  
  128. ##7.3.4.3 Hexadecimal Strings
  129. class PDFHexString(PDFObject):
  130.     def __init__(self,s):
  131.         PDFObject.__init__(self)
  132.         self.s=s
  133.  
  134.     def __str__(self):
  135.         return "<" + "".join(["%02x"%ord(c) for c in self.s]) + ">"
  136.  
  137. class PDFOctalString(PDFObject):
  138.     def __init__(self,s):
  139.         PDFObject.__init__(self)
  140.         self.s="".join(["\\%03o"%ord(c) for c in s])
  141.  
  142.     def __str__(self):
  143.         return "(%s)"%self.s
  144.  
  145.  
  146. ##7.3.4.2 Literal Strings
  147. class PDFString(PDFObject):
  148.     escapes = {'\x0a': '\\n',
  149.     '\x0d': '\\r',
  150.     '\x09': '\\t',
  151.     '\x08': '\\b',
  152.     '\xff': '\\f',
  153.     '(':    '\\(',
  154.     ')':    '\\)',
  155.     '\\':    '\\\\', }
  156.  
  157.     def __init__(self,s):
  158.         PDFObject.__init__(self)
  159.         self.s=s
  160.  
  161.     def __str__(self):
  162.         if random.randint(0,100) < 10:
  163.             return PDFHexString(self.s).__str__()
  164.         obfuscated = ""
  165.         for c in self.s:
  166.             if random.randint(0,100)>70:
  167.                  obfuscated+='\\%03o'%ord(c)
  168.             elif c in self.escapes.keys():
  169.                  obfuscated+=self.escapes[c]
  170.             else:
  171.                 obfuscated+=c
  172.             if random.randint(0,100) <10 :
  173.                 obfuscated+='\\\n'
  174.         return "(%s)"%obfuscated
  175.  
  176.  
  177. class PDFNum(PDFObject):
  178.     def __init__(self,s):
  179.         PDFObject.__init__(self)
  180.         self.s=s
  181.  
  182.     def __str__(self):
  183.         sign = ""
  184.         if random.randint(0,100)>50:
  185.             if self.s>0:
  186.                 sign = '+'
  187.             elif self.s<0:
  188.                 sign = '-'
  189.             elif random.randint(0,100)>50:
  190.                 sign = '-'
  191.             else:
  192.                 sign = '+'
  193.         obfuscated = ""
  194.         obfuscated += sign
  195.         obfuscated += putSome(['0'])
  196.         obfuscated += "%s"%self.s
  197.         if type(self.s)==type(0):
  198.             if random.randint(0,100)>60:
  199.                 obfuscated += "."+putSome(['0'])
  200.         else:
  201.             if random.randint(0,100)>60:
  202.                 obfuscated += putSome(['0'])
  203.         return obfuscated
  204.  
  205. class PDFBool(PDFObject):
  206.     def __init__(self,s):
  207.         PDFObject.__init__(self)
  208.         self.s=s
  209.  
  210.     def __str__(self):
  211.         if self.s:
  212.             return "true"
  213.         return "false"
  214.  
  215. class PDFRef(PDFObject):
  216.     def __init__(self,obj):
  217.         PDFObject.__init__(self)
  218.         self.obj=[obj]
  219.     def __str__(self):
  220.         return "%d %d R"%(self.obj[0].n,self.obj[0].v)
  221.  
  222. class PDFNull(PDFObject):
  223.     def __init__(self):
  224.         PDFObject.__init__(self)
  225.  
  226.     def __str__(self):
  227.         return "null"
  228.  
  229.  
  230. class PDFDoc():
  231.     def __init__(self,obfuscate=0):
  232.         self.objs=[]
  233.         self.info=None
  234.         self.root=None
  235.  
  236.     def setRoot(self,root):
  237.         self.root=root
  238.  
  239.     def setInfo(self,info):
  240.         self.info=info
  241.  
  242.     def _add(self,obj):
  243.         obj.v=0
  244.         obj.n=1+len(self.objs)
  245.         self.objs.append(obj)
  246.  
  247.     def add(self,obj):
  248.         if type(obj) != type([]):
  249.             self._add(obj)
  250.         else:
  251.             for o in obj:  
  252.                 self._add(o)
  253.  
  254.     def _header(self):
  255. ##Adobe suplement to ISO3200 3.4.1 File Header
  256.         header = "%"+random.choice(['!PS','PDF'])+"-%d.%d"%(random.randint(0,0xffffffff),random.randint(0,0xffffffff))
  257.         crap = ""
  258.         while len(crap) < random.randint(4,1024):
  259.             crap=crap+chr(random.choice(list(set(range(0,256))- set([chr(i) for i in [0x0a,0x0d]]))))
  260.         while len(header)<1024:
  261.             header = chr(random.randint(0,255))+header
  262.  
  263.         return header+"\n%"+crap+"\n"
  264.  
  265.     def __str__(self):
  266.         doc1 = self._header()
  267.         xref = {}
  268.         for obj in self.objs:
  269.             xref[obj.n] = len(doc1)
  270.             doc1+="%d %d obj\n"%(obj.n,obj.v)
  271.             doc1+=obj.__str__()
  272.             doc1+="\nendobj\n"
  273.         posxref=len(doc1)
  274.         doc1+="xref\n"
  275.         doc1+="0 %d\n"%(len(self.objs)+1)
  276.         doc1+="0000000000 65535 f \n"
  277.         for xr in xref.keys():
  278.             doc1+= "%010d %05d n \n"%(xref[xr],0)
  279.         doc1+="trailer\n"
  280.         trailer =  PDFDict()
  281.         trailer.add("Size",len(self.objs)+1)
  282.         trailer.add("Root",PDFRef(self.root))
  283.         if self.info:
  284.             trailer.add("Info",PDFRef(self.info))
  285.         doc1+=trailer.__str__()
  286.         doc1+="\nstartxref\n%d\n"%posxref
  287.         doc1+="%%EOF"
  288.  
  289.         return doc1
  290.  
RAW Paste Data