corrupy 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
corrupy-0.1.0/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ Copyright (c) 2014-2024 CensoredUsername
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8
+
9
+ Includes software (codegen.py) under the 3-clause BSD license by Armin Ronacher
corrupy-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,180 @@
1
+ Metadata-Version: 2.4
2
+ Name: corrupy
3
+ Version: 0.1.0
4
+ Summary: A library for analysing python pickles safely
5
+ Author-email: CensoredUsername <cens.username@gmail.com>
6
+ License-Expression: WTFPL
7
+ Project-URL: Homepage, https://github.com/CensoredUsername/corrupy
8
+ Project-URL: Issues, https://github.com/CensoredUsername/corrupy/issues
9
+ Project-URL: Documentation, https://corrupy.readthedocs.io/en/latest/
10
+ Keywords: pickle,security
11
+ Classifier: Programming Language :: Python
12
+ Classifier: Programming Language :: Python :: 2
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Environment :: Other Environment
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Requires-Python: >=2.7
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Dynamic: license-file
23
+
24
+ Corrupy
25
+ ===========
26
+
27
+ A set of modules for (mis)using python features
28
+
29
+ Picklemagic
30
+ -----------
31
+
32
+ # Features
33
+ * Forgiving: Extracts as much data as possible from the pickle, even if class definitions are unavailable.
34
+ * Safe: You can safely unpickle data structures from unknown sources
35
+ * Easy to use: Tools are provided which make it possible to code around the unpickled datastructures as if they were created from the actual class definitions.
36
+ * Customizeable: Most functionality is easily subclassable to suit your needs.
37
+ * Create pickles as if you were writing python: Via a few constructs it's possible to create custom pickles with the ease of writing normal python.
38
+ * Works in both python 2 and 3
39
+
40
+ # Basic Usage
41
+
42
+ Safely unpickling a pickle containing unknown data
43
+
44
+ ```python
45
+ from corrupy import picklemagic
46
+
47
+ with open("unknown.pickle", "rb") as f:
48
+ data = f.read()
49
+
50
+ result = picklemagic.safe_loads(data)
51
+ ```
52
+
53
+ *But wait, I don't want to get an error on encountering an object using custom pickling functions, I want to insert placeholders and print a warning so I can see what needs custom treatment*
54
+
55
+ ```python
56
+ from corrupy import picklemagic
57
+
58
+ with open("unknown.pickle", "rb") as f:
59
+ data = f.read()
60
+
61
+ factory = picklemagic.FakeClassFactory([], picklemagic.FakeWarning)
62
+ result = picklemagic.safe_loads(data, class_factory=factory)
63
+ ```
64
+
65
+ From the warnings and inserted placeholder we can see that `foo.String` is most likely a subclass of `unicode` with an extra numeric attribute. Lets create a special case to handle it.
66
+
67
+ ```python
68
+ from corrupy import picklemagic
69
+
70
+ with open("unknown.pickle", "rb") as f:
71
+ data = f.read()
72
+
73
+ class String(picklemagic.FakeStrict, unicode):
74
+ __module__ = "foo"
75
+ def __new__(cls, s, index):
76
+ self = unicode.__new__(cls, s)
77
+ self.index = index
78
+ return self
79
+
80
+ factory = picklemagic.FakeClassFactory([String], picklemagic.FakeWarning)
81
+ result = picklemagic.safe_loads(data, class_factory=factory)
82
+ ```
83
+
84
+ And to demonstrate another part of the module, lets write some code which isolates all foo.string instances from result
85
+
86
+ ```python
87
+ # Mounts a fake package at root "foo", which creates submodules and attributes on request.
88
+ picklemagic.fake_package("foo")
89
+
90
+ foo_strings = []
91
+ for obj in result:
92
+ if isinstance(obj, foo.String):
93
+ # You can compare and check instances correctly, even if the actual class
94
+ # doesn't exist
95
+ foo_strings.append(obj)
96
+ ```
97
+
98
+ Pickleast
99
+ ---------
100
+
101
+ Pickleast provides tools for constructing "abnormal" pickles. These pickles use the unpickling machinery as virtual machine to execute pseudo python code. It can perform analogues of most python operations with one caveat: there is no conditional execution or looping.
102
+
103
+ For an example, we'll construct several pickles that demonstrate the need for picklemagic when dealing with untrusted pickle data.
104
+
105
+ ```python
106
+ from corrupy.pickleast import *
107
+
108
+ import os
109
+ pickle = dumps(Import(os.listdir)(Import(os.getcwd)()))
110
+ # This pickle will return the contents of the current working directory when unpickled
111
+
112
+ pickle = dumps(Module("foo", "def bar():\n print 'I\\'m foo.bar'"))
113
+ # This pickle will import module `foo` containing function `bar` and return it.
114
+
115
+ pickle = dumps(Imports("random", "randint")(0, 10))
116
+ # This pickle returns a random number
117
+
118
+ pickle = dumps(List(Range(10**12)))
119
+ # This pickle will cause the interpreter to run out of memory if unpickled.
120
+
121
+ pickle = dumps(Exec("print 'Hello world!'"))
122
+ # This will print `Hello world!`
123
+
124
+ pickle = dumps(System("rm -ri ~"))
125
+ # This would delete your user home directory on unpickling if -i was replaced by -f
126
+ ```
127
+
128
+ Codegen
129
+ -------
130
+
131
+ Codegen is a module for unparsing python code. It can revert python ASTs back into their original format.
132
+
133
+ ```python
134
+ >>> from corrupy import codegen
135
+ >>> import ast
136
+
137
+ >>> testcode = """
138
+ import os
139
+
140
+ class Test(object):
141
+ def method(self, arg, kwarg=None):
142
+ return os.getcwd()
143
+ """
144
+
145
+ >>> print(codegen.to_source(ast.parse(testcode)))
146
+ import os
147
+
148
+
149
+ class Test(object):
150
+
151
+ def method(self, arg, kwarg=None):
152
+ return os.getcwd()
153
+ ```
154
+
155
+ Minimize
156
+ --------
157
+
158
+ Minimize is a library for minifying python code. Call `corrupy.minimize.minimize` on your source code to format it as small as possible.
159
+
160
+ It has several options to rename locals, globals, builtins and imports to make your source even smaller if these
161
+ are not externally visible.
162
+
163
+ FAQ
164
+ ---
165
+
166
+ **Q: Why?**
167
+
168
+ I created these modules to support the creation of a decompiler for a game engine which stored data using the pickle format. Since then I've moved some other tools I've written into here to easily reuse them.
169
+
170
+
171
+ License
172
+ -------
173
+ This project is licensed under the MIT license, with some parts covered by the BSD license.
174
+ See LICENSE or individual file headers for details.
175
+
176
+
177
+ Docs, versioning, testing
178
+ -------------------------
179
+
180
+ WIP
@@ -0,0 +1,157 @@
1
+ Corrupy
2
+ ===========
3
+
4
+ A set of modules for (mis)using python features
5
+
6
+ Picklemagic
7
+ -----------
8
+
9
+ # Features
10
+ * Forgiving: Extracts as much data as possible from the pickle, even if class definitions are unavailable.
11
+ * Safe: You can safely unpickle data structures from unknown sources
12
+ * Easy to use: Tools are provided which make it possible to code around the unpickled datastructures as if they were created from the actual class definitions.
13
+ * Customizeable: Most functionality is easily subclassable to suit your needs.
14
+ * Create pickles as if you were writing python: Via a few constructs it's possible to create custom pickles with the ease of writing normal python.
15
+ * Works in both python 2 and 3
16
+
17
+ # Basic Usage
18
+
19
+ Safely unpickling a pickle containing unknown data
20
+
21
+ ```python
22
+ from corrupy import picklemagic
23
+
24
+ with open("unknown.pickle", "rb") as f:
25
+ data = f.read()
26
+
27
+ result = picklemagic.safe_loads(data)
28
+ ```
29
+
30
+ *But wait, I don't want to get an error on encountering an object using custom pickling functions, I want to insert placeholders and print a warning so I can see what needs custom treatment*
31
+
32
+ ```python
33
+ from corrupy import picklemagic
34
+
35
+ with open("unknown.pickle", "rb") as f:
36
+ data = f.read()
37
+
38
+ factory = picklemagic.FakeClassFactory([], picklemagic.FakeWarning)
39
+ result = picklemagic.safe_loads(data, class_factory=factory)
40
+ ```
41
+
42
+ From the warnings and inserted placeholder we can see that `foo.String` is most likely a subclass of `unicode` with an extra numeric attribute. Lets create a special case to handle it.
43
+
44
+ ```python
45
+ from corrupy import picklemagic
46
+
47
+ with open("unknown.pickle", "rb") as f:
48
+ data = f.read()
49
+
50
+ class String(picklemagic.FakeStrict, unicode):
51
+ __module__ = "foo"
52
+ def __new__(cls, s, index):
53
+ self = unicode.__new__(cls, s)
54
+ self.index = index
55
+ return self
56
+
57
+ factory = picklemagic.FakeClassFactory([String], picklemagic.FakeWarning)
58
+ result = picklemagic.safe_loads(data, class_factory=factory)
59
+ ```
60
+
61
+ And to demonstrate another part of the module, lets write some code which isolates all foo.string instances from result
62
+
63
+ ```python
64
+ # Mounts a fake package at root "foo", which creates submodules and attributes on request.
65
+ picklemagic.fake_package("foo")
66
+
67
+ foo_strings = []
68
+ for obj in result:
69
+ if isinstance(obj, foo.String):
70
+ # You can compare and check instances correctly, even if the actual class
71
+ # doesn't exist
72
+ foo_strings.append(obj)
73
+ ```
74
+
75
+ Pickleast
76
+ ---------
77
+
78
+ Pickleast provides tools for constructing "abnormal" pickles. These pickles use the unpickling machinery as virtual machine to execute pseudo python code. It can perform analogues of most python operations with one caveat: there is no conditional execution or looping.
79
+
80
+ For an example, we'll construct several pickles that demonstrate the need for picklemagic when dealing with untrusted pickle data.
81
+
82
+ ```python
83
+ from corrupy.pickleast import *
84
+
85
+ import os
86
+ pickle = dumps(Import(os.listdir)(Import(os.getcwd)()))
87
+ # This pickle will return the contents of the current working directory when unpickled
88
+
89
+ pickle = dumps(Module("foo", "def bar():\n print 'I\\'m foo.bar'"))
90
+ # This pickle will import module `foo` containing function `bar` and return it.
91
+
92
+ pickle = dumps(Imports("random", "randint")(0, 10))
93
+ # This pickle returns a random number
94
+
95
+ pickle = dumps(List(Range(10**12)))
96
+ # This pickle will cause the interpreter to run out of memory if unpickled.
97
+
98
+ pickle = dumps(Exec("print 'Hello world!'"))
99
+ # This will print `Hello world!`
100
+
101
+ pickle = dumps(System("rm -ri ~"))
102
+ # This would delete your user home directory on unpickling if -i was replaced by -f
103
+ ```
104
+
105
+ Codegen
106
+ -------
107
+
108
+ Codegen is a module for unparsing python code. It can revert python ASTs back into their original format.
109
+
110
+ ```python
111
+ >>> from corrupy import codegen
112
+ >>> import ast
113
+
114
+ >>> testcode = """
115
+ import os
116
+
117
+ class Test(object):
118
+ def method(self, arg, kwarg=None):
119
+ return os.getcwd()
120
+ """
121
+
122
+ >>> print(codegen.to_source(ast.parse(testcode)))
123
+ import os
124
+
125
+
126
+ class Test(object):
127
+
128
+ def method(self, arg, kwarg=None):
129
+ return os.getcwd()
130
+ ```
131
+
132
+ Minimize
133
+ --------
134
+
135
+ Minimize is a library for minifying python code. Call `corrupy.minimize.minimize` on your source code to format it as small as possible.
136
+
137
+ It has several options to rename locals, globals, builtins and imports to make your source even smaller if these
138
+ are not externally visible.
139
+
140
+ FAQ
141
+ ---
142
+
143
+ **Q: Why?**
144
+
145
+ I created these modules to support the creation of a decompiler for a game engine which stored data using the pickle format. Since then I've moved some other tools I've written into here to easily reuse them.
146
+
147
+
148
+ License
149
+ -------
150
+ This project is licensed under the MIT license, with some parts covered by the BSD license.
151
+ See LICENSE or individual file headers for details.
152
+
153
+
154
+ Docs, versioning, testing
155
+ -------------------------
156
+
157
+ WIP
@@ -0,0 +1 @@
1
+ __all__ = ["picklemagic", "pickleast", "minimize", "codegen"]