python-obfuscation-framework 1.4.1__py3-none-any.whl
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.
- pof/__init__.py +21 -0
- pof/__main__.py +22 -0
- pof/cli.py +187 -0
- pof/errors.py +2 -0
- pof/evasion/__init__.py +57 -0
- pof/evasion/argv.py +44 -0
- pof/evasion/base.py +48 -0
- pof/evasion/cpu/__init__.py +0 -0
- pof/evasion/cpu/cpu_count.py +27 -0
- pof/evasion/fs/__init__.py +0 -0
- pof/evasion/fs/directory_exist.py +29 -0
- pof/evasion/fs/directory_list_exist.py +46 -0
- pof/evasion/fs/directory_list_missing.py +45 -0
- pof/evasion/fs/directory_missing.py +28 -0
- pof/evasion/fs/exec_method.py +51 -0
- pof/evasion/fs/executable_path.py +66 -0
- pof/evasion/fs/file_exist.py +29 -0
- pof/evasion/fs/file_list_exist.py +46 -0
- pof/evasion/fs/file_list_missing.py +45 -0
- pof/evasion/fs/file_missing.py +31 -0
- pof/evasion/fs/tmp.py +112 -0
- pof/evasion/hardware/__init__.py +0 -0
- pof/evasion/hardware/ram_count.py +50 -0
- pof/evasion/hooks/__init__.py +0 -0
- pof/evasion/hooks/debugger.py +36 -0
- pof/evasion/hooks/tracemalloc.py +23 -0
- pof/evasion/human/__init__.py +0 -0
- pof/evasion/human/p.py +45 -0
- pof/evasion/human/prompt.py +69 -0
- pof/evasion/integrity.py +129 -0
- pof/evasion/multi.py +41 -0
- pof/evasion/os/__init__.py +0 -0
- pof/evasion/os/domain.py +27 -0
- pof/evasion/os/hostname.py +27 -0
- pof/evasion/os/uid.py +28 -0
- pof/evasion/os/username.py +27 -0
- pof/evasion/processes/__init__.py +0 -0
- pof/evasion/processes/proc_count.py +47 -0
- pof/evasion/time/__init__.py +0 -0
- pof/evasion/time/expire.py +75 -0
- pof/evasion/time/uptime.py +48 -0
- pof/evasion/time/utc.py +26 -0
- pof/evasion/utils.py +198 -0
- pof/main.py +369 -0
- pof/obfuscator/__init__.py +86 -0
- pof/obfuscator/builtins.py +482 -0
- pof/obfuscator/cipher/__init__.py +0 -0
- pof/obfuscator/cipher/deep_encryption.py +194 -0
- pof/obfuscator/cipher/rc4.py +22 -0
- pof/obfuscator/cipher/shift.py +19 -0
- pof/obfuscator/cipher/xor.py +121 -0
- pof/obfuscator/compression/__init__.py +0 -0
- pof/obfuscator/compression/bz2.py +22 -0
- pof/obfuscator/compression/gzip.py +22 -0
- pof/obfuscator/compression/lzma.py +22 -0
- pof/obfuscator/compression/zlib.py +22 -0
- pof/obfuscator/constants.py +294 -0
- pof/obfuscator/definitions.py +341 -0
- pof/obfuscator/encoding/__init__.py +0 -0
- pof/obfuscator/encoding/a85.py +21 -0
- pof/obfuscator/encoding/b16.py +21 -0
- pof/obfuscator/encoding/b32.py +21 -0
- pof/obfuscator/encoding/b32hex.py +21 -0
- pof/obfuscator/encoding/b64.py +21 -0
- pof/obfuscator/encoding/b85.py +25 -0
- pof/obfuscator/encoding/binascii.py +22 -0
- pof/obfuscator/encoding/snt.py +23 -0
- pof/obfuscator/esoteric/__init__.py +0 -0
- pof/obfuscator/esoteric/call.py +49 -0
- pof/obfuscator/esoteric/doc.py +237 -0
- pof/obfuscator/esoteric/globals.py +62 -0
- pof/obfuscator/esoteric/imports.py +55 -0
- pof/obfuscator/extract_variables.py +297 -0
- pof/obfuscator/junk/__init__.py +0 -0
- pof/obfuscator/junk/add_comments.py +102 -0
- pof/obfuscator/junk/add_newlines.py +36 -0
- pof/obfuscator/names.py +474 -0
- pof/obfuscator/names_rope.py +375 -0
- pof/obfuscator/numbers.py +271 -0
- pof/obfuscator/other/__init__.py +0 -0
- pof/obfuscator/other/tokens.py +47 -0
- pof/obfuscator/remove/__init__.py +0 -0
- pof/obfuscator/remove/comments.py +36 -0
- pof/obfuscator/remove/exceptions.py +75 -0
- pof/obfuscator/remove/indents.py +28 -0
- pof/obfuscator/remove/loggings.py +120 -0
- pof/obfuscator/remove/loggings_old.py +45 -0
- pof/obfuscator/remove/newline.py +27 -0
- pof/obfuscator/remove/print.py +40 -0
- pof/obfuscator/restructure.py +15 -0
- pof/obfuscator/stegano/__init__.py +0 -0
- pof/obfuscator/stegano/docstrings.py +111 -0
- pof/obfuscator/stegano/ipv6encoding.py +21 -0
- pof/obfuscator/stegano/macencoding.py +21 -0
- pof/obfuscator/stegano/uuidencoding.py +21 -0
- pof/obfuscator/strings.py +359 -0
- pof/stager/__init__.py +17 -0
- pof/stager/cipher/__init__.py +0 -0
- pof/stager/cipher/rc4.py +36 -0
- pof/stager/download.py +80 -0
- pof/stager/image.py +374 -0
- pof/stager/lots/__init__.py +1 -0
- pof/stager/lots/cl1pnet.py +51 -0
- pof/stager/lots/pastebin.py +35 -0
- pof/stager/lots/pasters.py +30 -0
- pof/stager/quine.py +135 -0
- pof/utils/__init__.py +0 -0
- pof/utils/cipher/__init__.py +7 -0
- pof/utils/cipher/rc4.py +407 -0
- pof/utils/cipher/shift.py +41 -0
- pof/utils/compression/__init__.py +11 -0
- pof/utils/compression/bz2.py +38 -0
- pof/utils/compression/gzip.py +38 -0
- pof/utils/compression/lzma.py +38 -0
- pof/utils/compression/zlib.py +38 -0
- pof/utils/encoding/__init__.py +19 -0
- pof/utils/encoding/a85.py +35 -0
- pof/utils/encoding/b16.py +30 -0
- pof/utils/encoding/b3.py +93 -0
- pof/utils/encoding/b32.py +30 -0
- pof/utils/encoding/b32hex.py +30 -0
- pof/utils/encoding/b64.py +30 -0
- pof/utils/encoding/b85.py +35 -0
- pof/utils/encoding/binascii.py +38 -0
- pof/utils/encoding/snt.py +97 -0
- pof/utils/entropy.py +24 -0
- pof/utils/extract_names.py +204 -0
- pof/utils/generator/__init__.py +17 -0
- pof/utils/generator/advanced.py +53 -0
- pof/utils/generator/base.py +178 -0
- pof/utils/generator/basic.py +107 -0
- pof/utils/generator/names.txt +37241 -0
- pof/utils/generator/unicode.py +171 -0
- pof/utils/se/__init__.py +3 -0
- pof/utils/se/homoglyphs.py +99 -0
- pof/utils/se/homoglyphs.txt +96 -0
- pof/utils/stegano/__init__.py +5 -0
- pof/utils/stegano/ipv6encoding.py +97 -0
- pof/utils/stegano/macencoding.py +96 -0
- pof/utils/stegano/uuidencoding.py +102 -0
- pof/utils/tokens.py +68 -0
- python_obfuscation_framework-1.4.1.dist-info/LICENSE +674 -0
- python_obfuscation_framework-1.4.1.dist-info/METADATA +851 -0
- python_obfuscation_framework-1.4.1.dist-info/RECORD +147 -0
- python_obfuscation_framework-1.4.1.dist-info/WHEEL +5 -0
- python_obfuscation_framework-1.4.1.dist-info/entry_points.txt +2 -0
- python_obfuscation_framework-1.4.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from tokenize import LPAR, NAME, OP, RPAR, STRING
|
|
2
|
+
|
|
3
|
+
from pof.evasion.base import BaseEvasion
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class FileExistEvasion(BaseEvasion):
|
|
7
|
+
def __init__(self, file) -> None:
|
|
8
|
+
self.file = file
|
|
9
|
+
|
|
10
|
+
@staticmethod
|
|
11
|
+
def import_tokens():
|
|
12
|
+
return [
|
|
13
|
+
(NAME, "import"),
|
|
14
|
+
(NAME, "os"),
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
def check_tokens(self):
|
|
18
|
+
"""`not os.path.isfile('/tmp/a')`."""
|
|
19
|
+
return [
|
|
20
|
+
(NAME, "not"),
|
|
21
|
+
(NAME, "os"),
|
|
22
|
+
(OP, "."),
|
|
23
|
+
(NAME, "path"),
|
|
24
|
+
(OP, "."),
|
|
25
|
+
(NAME, "isfile"),
|
|
26
|
+
(LPAR, "("),
|
|
27
|
+
(STRING, repr(self.file)),
|
|
28
|
+
(RPAR, ")"),
|
|
29
|
+
]
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import io
|
|
2
|
+
from tokenize import LPAR, NAME, OP, RPAR, generate_tokens
|
|
3
|
+
|
|
4
|
+
from pof.evasion.base import BaseEvasion
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class FileListExistEvasion(BaseEvasion):
|
|
8
|
+
def __init__(self, file_list) -> None:
|
|
9
|
+
self.file_list = file_list
|
|
10
|
+
|
|
11
|
+
@staticmethod
|
|
12
|
+
def import_tokens():
|
|
13
|
+
return [
|
|
14
|
+
(NAME, "import"),
|
|
15
|
+
(NAME, "os"),
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
def check_tokens(self):
|
|
19
|
+
"""Trigger evasion if any file from the list is absent on the system.
|
|
20
|
+
|
|
21
|
+
`not all([os.path.isfile(p)for p in['/tmp/a','/tmp/b',...]])`
|
|
22
|
+
"""
|
|
23
|
+
# TODO (deoktr): change
|
|
24
|
+
io_obj = io.StringIO(repr(self.file_list))
|
|
25
|
+
file_list_tokens = list(generate_tokens(io_obj.readline))
|
|
26
|
+
|
|
27
|
+
return [
|
|
28
|
+
(NAME, "not"),
|
|
29
|
+
(NAME, "all"),
|
|
30
|
+
(LPAR, "("),
|
|
31
|
+
(OP, "["),
|
|
32
|
+
(NAME, "os"),
|
|
33
|
+
(OP, "."),
|
|
34
|
+
(NAME, "path"),
|
|
35
|
+
(OP, "."),
|
|
36
|
+
(NAME, "isfile"),
|
|
37
|
+
(LPAR, "("),
|
|
38
|
+
(NAME, "p"),
|
|
39
|
+
(RPAR, ")"),
|
|
40
|
+
(NAME, "for"),
|
|
41
|
+
(NAME, "p"),
|
|
42
|
+
(NAME, "in"),
|
|
43
|
+
*file_list_tokens,
|
|
44
|
+
(OP, "]"),
|
|
45
|
+
(RPAR, ")"),
|
|
46
|
+
]
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import io
|
|
2
|
+
from tokenize import LPAR, NAME, OP, RPAR, generate_tokens
|
|
3
|
+
|
|
4
|
+
from pof.evasion.base import BaseEvasion
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class FileListMissingEvasion(BaseEvasion):
|
|
8
|
+
def __init__(self, file_list) -> None:
|
|
9
|
+
self.file_list = file_list
|
|
10
|
+
|
|
11
|
+
@staticmethod
|
|
12
|
+
def import_tokens():
|
|
13
|
+
return [
|
|
14
|
+
(NAME, "import"),
|
|
15
|
+
(NAME, "os"),
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
def check_tokens(self):
|
|
19
|
+
"""Trigger evasion if any file from the list is present on the system.
|
|
20
|
+
|
|
21
|
+
`any([os.path.isfile(p) for p in ['/tmp/a', '/tmp/b', ...]])`
|
|
22
|
+
"""
|
|
23
|
+
# TODO (deoktr): change
|
|
24
|
+
io_obj = io.StringIO(repr(self.file_list))
|
|
25
|
+
file_list_tokens = list(generate_tokens(io_obj.readline))
|
|
26
|
+
|
|
27
|
+
return [
|
|
28
|
+
(NAME, "any"),
|
|
29
|
+
(LPAR, "("),
|
|
30
|
+
(OP, "["),
|
|
31
|
+
(NAME, "os"),
|
|
32
|
+
(OP, "."),
|
|
33
|
+
(NAME, "path"),
|
|
34
|
+
(OP, "."),
|
|
35
|
+
(NAME, "isfile"),
|
|
36
|
+
(LPAR, "("),
|
|
37
|
+
(NAME, "p"),
|
|
38
|
+
(RPAR, ")"),
|
|
39
|
+
(NAME, "for"),
|
|
40
|
+
(NAME, "p"),
|
|
41
|
+
(NAME, "in"),
|
|
42
|
+
*file_list_tokens,
|
|
43
|
+
(OP, "]"),
|
|
44
|
+
(RPAR, ")"),
|
|
45
|
+
]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from tokenize import LPAR, NAME, OP, RPAR, STRING
|
|
2
|
+
|
|
3
|
+
from pof.evasion.base import BaseEvasion
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class FileMissingEvasion(BaseEvasion):
|
|
7
|
+
def __init__(self, file) -> None:
|
|
8
|
+
self.file = file
|
|
9
|
+
|
|
10
|
+
@staticmethod
|
|
11
|
+
def import_tokens():
|
|
12
|
+
return [
|
|
13
|
+
(NAME, "import"),
|
|
14
|
+
(NAME, "os"),
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
def check_tokens(self):
|
|
18
|
+
"""Trigger evasion if a file is present on the system.
|
|
19
|
+
|
|
20
|
+
`os.path.isfile('/tmp/a')`
|
|
21
|
+
"""
|
|
22
|
+
return [
|
|
23
|
+
(NAME, "os"),
|
|
24
|
+
(OP, "."),
|
|
25
|
+
(NAME, "path"),
|
|
26
|
+
(OP, "."),
|
|
27
|
+
(NAME, "isfile"),
|
|
28
|
+
(LPAR, "("),
|
|
29
|
+
(STRING, repr(self.file)),
|
|
30
|
+
(RPAR, ")"),
|
|
31
|
+
]
|
pof/evasion/fs/tmp.py
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
from tokenize import LPAR, NAME, OP, RPAR, STRING
|
|
2
|
+
|
|
3
|
+
from pof.evasion.base import BaseEvasion
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TmpCountEvasion(BaseEvasion):
|
|
7
|
+
"""Cross-platform evasion that count the number of temp files."""
|
|
8
|
+
|
|
9
|
+
def __init__(self, tmp_count=5) -> None:
|
|
10
|
+
self.tmp_count = tmp_count
|
|
11
|
+
|
|
12
|
+
@staticmethod
|
|
13
|
+
def import_tokens():
|
|
14
|
+
return [
|
|
15
|
+
(NAME, "import"),
|
|
16
|
+
(NAME, "os"),
|
|
17
|
+
(OP, ","),
|
|
18
|
+
(NAME, "sys"),
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
def check_tokens(self):
|
|
22
|
+
r"""Check the number of files present in /tmp.
|
|
23
|
+
|
|
24
|
+
`len(os.listdir("/tmp"if sys.platform!="windows"else"C:\windows\temp"))<10`
|
|
25
|
+
"""
|
|
26
|
+
return [
|
|
27
|
+
(NAME, "len"),
|
|
28
|
+
(LPAR, "("),
|
|
29
|
+
(NAME, "os"),
|
|
30
|
+
(OP, "."),
|
|
31
|
+
(NAME, "listdir"),
|
|
32
|
+
(LPAR, "("),
|
|
33
|
+
(STRING, repr("/tmp")), # noqa: S108
|
|
34
|
+
(NAME, "if"),
|
|
35
|
+
(NAME, "sys"),
|
|
36
|
+
(OP, "."),
|
|
37
|
+
(NAME, "platform"),
|
|
38
|
+
(OP, "!="),
|
|
39
|
+
(STRING, repr("windows")),
|
|
40
|
+
(NAME, "else"),
|
|
41
|
+
(STRING, repr("C:\\windows\\temp")),
|
|
42
|
+
(RPAR, ")"),
|
|
43
|
+
(RPAR, ")"),
|
|
44
|
+
(OP, "<"),
|
|
45
|
+
(STRING, repr(self.tmp_count)),
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class LinuxTmpCountEvasion(BaseEvasion):
|
|
50
|
+
def __init__(self, tmp_count=5) -> None:
|
|
51
|
+
self.tmp_count = tmp_count
|
|
52
|
+
|
|
53
|
+
@staticmethod
|
|
54
|
+
def import_tokens():
|
|
55
|
+
return [
|
|
56
|
+
(NAME, "import"),
|
|
57
|
+
(NAME, "os"),
|
|
58
|
+
(OP, ","),
|
|
59
|
+
(NAME, "sys"),
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
def check_tokens(self):
|
|
63
|
+
"""Check the number of files present in /tmp.
|
|
64
|
+
|
|
65
|
+
`len(os.listdir("/tmp")) < 10`
|
|
66
|
+
"""
|
|
67
|
+
return [
|
|
68
|
+
(NAME, "len"),
|
|
69
|
+
(LPAR, "("),
|
|
70
|
+
(NAME, "os"),
|
|
71
|
+
(OP, "."),
|
|
72
|
+
(NAME, "listdir"),
|
|
73
|
+
(LPAR, "("),
|
|
74
|
+
(STRING, repr("/tmp")), # noqa: S108
|
|
75
|
+
(RPAR, ")"),
|
|
76
|
+
(RPAR, ")"),
|
|
77
|
+
(OP, "<"),
|
|
78
|
+
(STRING, repr(self.tmp_count)),
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class WinTmpCountEvasion(BaseEvasion):
|
|
83
|
+
def __init__(self, tmp_count=5) -> None:
|
|
84
|
+
self.tmp_count = tmp_count
|
|
85
|
+
|
|
86
|
+
@staticmethod
|
|
87
|
+
def import_tokens():
|
|
88
|
+
return [
|
|
89
|
+
(NAME, "import"),
|
|
90
|
+
(NAME, "os"),
|
|
91
|
+
(OP, ","),
|
|
92
|
+
(NAME, "sys"),
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
def check_tokens(self):
|
|
96
|
+
r"""Check the number of files present in /tmp.
|
|
97
|
+
|
|
98
|
+
`len(os.listdir("C:\windows\temp")) < 10`
|
|
99
|
+
"""
|
|
100
|
+
return [
|
|
101
|
+
(NAME, "len"),
|
|
102
|
+
(LPAR, "("),
|
|
103
|
+
(NAME, "os"),
|
|
104
|
+
(OP, "."),
|
|
105
|
+
(NAME, "listdir"),
|
|
106
|
+
(LPAR, "("),
|
|
107
|
+
(STRING, repr(r"C:\windows\temp")),
|
|
108
|
+
(RPAR, ")"),
|
|
109
|
+
(RPAR, ")"),
|
|
110
|
+
(OP, "<"),
|
|
111
|
+
(STRING, repr(self.tmp_count)),
|
|
112
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# TODO (deoktr): make windows version
|
|
2
|
+
from tokenize import LPAR, NAME, NUMBER, OP, RPAR, STRING
|
|
3
|
+
|
|
4
|
+
from pof.evasion.base import BaseEvasion
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class LinuxRAMCountEvasion(BaseEvasion):
|
|
8
|
+
def __init__(self, min_ram: int = 2) -> None:
|
|
9
|
+
"""Min RAM in Gib."""
|
|
10
|
+
self.min_ram = min_ram
|
|
11
|
+
|
|
12
|
+
@staticmethod
|
|
13
|
+
def import_tokens() -> list[tuple[int, str]]:
|
|
14
|
+
return [
|
|
15
|
+
(NAME, "import"),
|
|
16
|
+
(NAME, "os"),
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
def check_tokens(self) -> list[tuple[int, str]]:
|
|
20
|
+
"""Linux RAM count evasion tokens.
|
|
21
|
+
|
|
22
|
+
`((os.sysconf('SC_PAGE_SIZE') * os.sysconf('SC_PHYS_PAGES')) / (1024.**3)) < 2`
|
|
23
|
+
"""
|
|
24
|
+
return [
|
|
25
|
+
(LPAR, "("),
|
|
26
|
+
(LPAR, "("),
|
|
27
|
+
(NAME, "os"),
|
|
28
|
+
(OP, "."),
|
|
29
|
+
(NAME, "sysconf"),
|
|
30
|
+
(LPAR, "("),
|
|
31
|
+
(STRING, "'SC_PAGE_SIZE'"),
|
|
32
|
+
(RPAR, ")"),
|
|
33
|
+
(OP, "*"),
|
|
34
|
+
(NAME, "os"),
|
|
35
|
+
(OP, "."),
|
|
36
|
+
(NAME, "sysconf"),
|
|
37
|
+
(LPAR, "("),
|
|
38
|
+
(STRING, "'SC_PHYS_PAGES'"),
|
|
39
|
+
(RPAR, ")"),
|
|
40
|
+
(RPAR, ")"),
|
|
41
|
+
(OP, "/"),
|
|
42
|
+
(LPAR, "("),
|
|
43
|
+
(NUMBER, "1024."),
|
|
44
|
+
(OP, "**"),
|
|
45
|
+
(NUMBER, "3"),
|
|
46
|
+
(RPAR, ")"),
|
|
47
|
+
(RPAR, ")"),
|
|
48
|
+
(OP, "<"),
|
|
49
|
+
(NUMBER, str(self.min_ram)),
|
|
50
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from tokenize import LPAR, NAME, OP, RPAR, STRING
|
|
2
|
+
|
|
3
|
+
from pof.evasion.base import BaseEvasion
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DebuggerEvasion(BaseEvasion):
|
|
7
|
+
@staticmethod
|
|
8
|
+
def import_tokens():
|
|
9
|
+
return [
|
|
10
|
+
(NAME, "import"),
|
|
11
|
+
(NAME, "sys"),
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
@staticmethod
|
|
15
|
+
def check_tokens():
|
|
16
|
+
"""Detect Python debugger.
|
|
17
|
+
|
|
18
|
+
`hasattr(sys, 'gettrace') and sys.gettrace() is not None`
|
|
19
|
+
"""
|
|
20
|
+
return [
|
|
21
|
+
(NAME, "hasattr"),
|
|
22
|
+
(LPAR, "("),
|
|
23
|
+
(NAME, "sys"),
|
|
24
|
+
(OP, ","),
|
|
25
|
+
(STRING, "'gettrace'"),
|
|
26
|
+
(RPAR, ")"),
|
|
27
|
+
(NAME, "and"),
|
|
28
|
+
(NAME, "sys"),
|
|
29
|
+
(OP, "."),
|
|
30
|
+
(NAME, "gettrace"),
|
|
31
|
+
(LPAR, "("),
|
|
32
|
+
(RPAR, ")"),
|
|
33
|
+
(NAME, "is"),
|
|
34
|
+
(NAME, "not"),
|
|
35
|
+
(NAME, "None"),
|
|
36
|
+
]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from tokenize import LPAR, NAME, OP, RPAR
|
|
2
|
+
|
|
3
|
+
from pof.evasion.base import BaseEvasion
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TracemallocEvasion(BaseEvasion):
|
|
7
|
+
@staticmethod
|
|
8
|
+
def import_tokens():
|
|
9
|
+
return [
|
|
10
|
+
(NAME, "import"),
|
|
11
|
+
(NAME, "tracemalloc"),
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
@staticmethod
|
|
15
|
+
def check_tokens():
|
|
16
|
+
"""`tracemalloc.is_tracing()`."""
|
|
17
|
+
return [
|
|
18
|
+
(NAME, "tracemalloc"),
|
|
19
|
+
(OP, "."),
|
|
20
|
+
(NAME, "is_tracing"),
|
|
21
|
+
(LPAR, "("),
|
|
22
|
+
(RPAR, ")"),
|
|
23
|
+
]
|
|
File without changes
|
pof/evasion/human/p.py
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
def promt_unix():
|
|
2
|
+
# TODO (deoktr): add try: except around tkinter imports
|
|
3
|
+
from tkinter import E, S, Tk, ttk
|
|
4
|
+
|
|
5
|
+
root = Tk()
|
|
6
|
+
|
|
7
|
+
clicked = False
|
|
8
|
+
|
|
9
|
+
# FIXME (deoktr): Doesn't work ...
|
|
10
|
+
def click():
|
|
11
|
+
root.destroy()
|
|
12
|
+
|
|
13
|
+
root.title("System Error")
|
|
14
|
+
root.resizable(0, 0) # block resize
|
|
15
|
+
|
|
16
|
+
root.overrideredirect(1) # hide window
|
|
17
|
+
|
|
18
|
+
root.geometry(
|
|
19
|
+
"+%d+%d" # noqa: UP031
|
|
20
|
+
% (
|
|
21
|
+
(root.winfo_screenwidth() / 2) - (root.winfo_reqwidth() / 2),
|
|
22
|
+
(root.winfo_screenheight() / 2) - (root.winfo_reqheight() / 2),
|
|
23
|
+
),
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
root.after(int(5 * 1000), func=root.destroy)
|
|
27
|
+
|
|
28
|
+
frm = ttk.Frame(root, padding="50 12 50 12")
|
|
29
|
+
frm.grid()
|
|
30
|
+
ttk.Label(frm, text="System error 0x02333").grid(column=0, row=0)
|
|
31
|
+
ttk.Button(frm, text="Close", command=click).grid(column=0, row=1, sticky=(E, S))
|
|
32
|
+
root.mainloop()
|
|
33
|
+
return clicked
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
if __name__ == "__main__":
|
|
37
|
+
import sys
|
|
38
|
+
|
|
39
|
+
if not promt_unix():
|
|
40
|
+
msg = "did not click"
|
|
41
|
+
sys.stdout(msg)
|
|
42
|
+
sys.exit(1)
|
|
43
|
+
|
|
44
|
+
sys.stdout("Hello, world!")
|
|
45
|
+
sys.exit(0)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# just prompt the user with a dialog box
|
|
2
|
+
# TODO (deoktr): test
|
|
3
|
+
# TODO (deoktr): make a version for linux somehow
|
|
4
|
+
# TODO (deoktr): close prompt after a certain time
|
|
5
|
+
from tokenize import LPAR, NAME, OP, RPAR, STRING
|
|
6
|
+
|
|
7
|
+
from pof.evasion.base import BaseEvasion
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class PromptBase:
|
|
11
|
+
def __init__(self, title=None, message=None) -> None:
|
|
12
|
+
# TODO (deoktr): generate randomly the message and title
|
|
13
|
+
if title is None:
|
|
14
|
+
title = "System Error 0x18463832"
|
|
15
|
+
if message is None:
|
|
16
|
+
message = "Your system encountered an error, please click OK to proceed"
|
|
17
|
+
|
|
18
|
+
self.message = message
|
|
19
|
+
self.title = title
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class LinuxPromptEvasion(BaseEvasion, PromptBase):
|
|
23
|
+
"""Prompt the user.
|
|
24
|
+
|
|
25
|
+
Tkinter is required to prompt user on unix systems, you'll need the `libtk?`
|
|
26
|
+
library. Run either `apt-get install tk`, `pacman -S tk` or `dnf install tk`.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
@staticmethod
|
|
30
|
+
def check_tokens():
|
|
31
|
+
"""Evasion is triggered if the message box is not pressed.
|
|
32
|
+
|
|
33
|
+
``
|
|
34
|
+
"""
|
|
35
|
+
return [
|
|
36
|
+
# TODO (deoktr): check file `p.py` in the same directory
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class WinPromptEvasion(BaseEvasion, PromptBase):
|
|
41
|
+
@staticmethod
|
|
42
|
+
def import_tokens():
|
|
43
|
+
return [
|
|
44
|
+
(NAME, "import"),
|
|
45
|
+
(NAME, "ctypes"),
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
def check_tokens(self):
|
|
49
|
+
"""Evasion is triggered if the message box is not pressed.
|
|
50
|
+
|
|
51
|
+
`ctypes.windll.user32.MessageBoxW(None, message, title)`
|
|
52
|
+
"""
|
|
53
|
+
return [
|
|
54
|
+
(NAME, "not"),
|
|
55
|
+
(NAME, "ctypes"),
|
|
56
|
+
(OP, "."),
|
|
57
|
+
(NAME, "windll"),
|
|
58
|
+
(OP, "."),
|
|
59
|
+
(NAME, "user32"),
|
|
60
|
+
(OP, "."),
|
|
61
|
+
(NAME, "MessageBoxW"),
|
|
62
|
+
(LPAR, "("),
|
|
63
|
+
(NAME, "None"),
|
|
64
|
+
(OP, ","),
|
|
65
|
+
(STRING, repr(self.message)),
|
|
66
|
+
(OP, ","),
|
|
67
|
+
(STRING, repr(self.title)),
|
|
68
|
+
(RPAR, ")"),
|
|
69
|
+
]
|
pof/evasion/integrity.py
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
from tokenize import DEDENT, INDENT, LPAR, NAME, NEWLINE, OP, RPAR, STRING
|
|
2
|
+
|
|
3
|
+
from pof.evasion.base import BaseEvasion
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class IntegrityEvasion(BaseEvasion):
|
|
7
|
+
@staticmethod
|
|
8
|
+
def import_tokens():
|
|
9
|
+
return [
|
|
10
|
+
(NAME, "import"),
|
|
11
|
+
(NAME, "hashlib"),
|
|
12
|
+
(OP, ","),
|
|
13
|
+
(NAME, "inspect"),
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
@staticmethod
|
|
17
|
+
def integrity_function_tokens():
|
|
18
|
+
"""Integrity check tokens.
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
def integrity(ihash):
|
|
22
|
+
stack = ""
|
|
23
|
+
for obj in [integrity]:
|
|
24
|
+
stack += inspect.getsource(obj)
|
|
25
|
+
m = hashlib.sha3_512()
|
|
26
|
+
m.update(stack.encode())
|
|
27
|
+
m.digest()
|
|
28
|
+
h = m.hexdigest()
|
|
29
|
+
return h != ihash
|
|
30
|
+
# code...
|
|
31
|
+
```
|
|
32
|
+
"""
|
|
33
|
+
return [
|
|
34
|
+
(NAME, "def"),
|
|
35
|
+
(NAME, "integrity"),
|
|
36
|
+
(OP, "("),
|
|
37
|
+
(NAME, "ihash"),
|
|
38
|
+
(OP, ")"),
|
|
39
|
+
(OP, ":"),
|
|
40
|
+
(NEWLINE, "\n"),
|
|
41
|
+
(INDENT, " "),
|
|
42
|
+
(NAME, "stack"),
|
|
43
|
+
(OP, "="),
|
|
44
|
+
(STRING, '""'),
|
|
45
|
+
(NEWLINE, "\n"),
|
|
46
|
+
(NAME, "for"),
|
|
47
|
+
(NAME, "obj"),
|
|
48
|
+
(NAME, "in"),
|
|
49
|
+
(OP, "["),
|
|
50
|
+
(NAME, "integrity"),
|
|
51
|
+
(OP, "]"),
|
|
52
|
+
(OP, ":"),
|
|
53
|
+
(NEWLINE, "\n"),
|
|
54
|
+
(INDENT, " "),
|
|
55
|
+
(NAME, "stack"),
|
|
56
|
+
(OP, "+="),
|
|
57
|
+
(NAME, "inspect"),
|
|
58
|
+
(OP, "."),
|
|
59
|
+
(NAME, "getsource"),
|
|
60
|
+
(OP, "("),
|
|
61
|
+
(NAME, "obj"),
|
|
62
|
+
(OP, ")"),
|
|
63
|
+
(NEWLINE, "\n"),
|
|
64
|
+
(DEDENT, ""),
|
|
65
|
+
(NAME, "m"),
|
|
66
|
+
(OP, "="),
|
|
67
|
+
(NAME, "hashlib"),
|
|
68
|
+
(OP, "."),
|
|
69
|
+
(NAME, "sha3_512"),
|
|
70
|
+
(OP, "("),
|
|
71
|
+
(OP, ")"),
|
|
72
|
+
(NEWLINE, "\n"),
|
|
73
|
+
(NAME, "m"),
|
|
74
|
+
(OP, "."),
|
|
75
|
+
(NAME, "update"),
|
|
76
|
+
(OP, "("),
|
|
77
|
+
(NAME, "stack"),
|
|
78
|
+
(OP, "."),
|
|
79
|
+
(NAME, "encode"),
|
|
80
|
+
(OP, "("),
|
|
81
|
+
(OP, ")"),
|
|
82
|
+
(OP, ")"),
|
|
83
|
+
(NEWLINE, "\n"),
|
|
84
|
+
(NAME, "m"),
|
|
85
|
+
(OP, "."),
|
|
86
|
+
(NAME, "digest"),
|
|
87
|
+
(OP, "("),
|
|
88
|
+
(OP, ")"),
|
|
89
|
+
(NEWLINE, "\n"),
|
|
90
|
+
(NAME, "h"),
|
|
91
|
+
(OP, "="),
|
|
92
|
+
(NAME, "m"),
|
|
93
|
+
(OP, "."),
|
|
94
|
+
(NAME, "hexdigest"),
|
|
95
|
+
(OP, "("),
|
|
96
|
+
(OP, ")"),
|
|
97
|
+
(NEWLINE, "\n"),
|
|
98
|
+
(NAME, "return"),
|
|
99
|
+
(NAME, "h"),
|
|
100
|
+
(OP, "!="),
|
|
101
|
+
(NAME, "ihash"),
|
|
102
|
+
(NEWLINE, "\n"),
|
|
103
|
+
(DEDENT, ""),
|
|
104
|
+
]
|
|
105
|
+
|
|
106
|
+
@classmethod
|
|
107
|
+
def add_evasion(cls, tokens):
|
|
108
|
+
"""Detect if the source code has been tampered.
|
|
109
|
+
|
|
110
|
+
Only works when executing from a file.
|
|
111
|
+
"""
|
|
112
|
+
return [
|
|
113
|
+
*cls.import_tokens(),
|
|
114
|
+
(NEWLINE, "\n"),
|
|
115
|
+
(NAME, "if"),
|
|
116
|
+
(LPAR, "("),
|
|
117
|
+
(NAME, "integrity"),
|
|
118
|
+
(OP, "("),
|
|
119
|
+
(STRING, '"a"'),
|
|
120
|
+
(OP, ")"),
|
|
121
|
+
(RPAR, ")"),
|
|
122
|
+
(OP, ":"),
|
|
123
|
+
(NEWLINE, "\n"),
|
|
124
|
+
(INDENT, " "),
|
|
125
|
+
*cls.fail_call_tokens(),
|
|
126
|
+
(NEWLINE, "\n"),
|
|
127
|
+
(DEDENT, ""),
|
|
128
|
+
*tokens,
|
|
129
|
+
]
|
pof/evasion/multi.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from tokenize import NEWLINE, OP
|
|
2
|
+
|
|
3
|
+
from .cpu.cpu_count import CPUCountEvasion
|
|
4
|
+
from .hooks.debugger import DebuggerEvasion
|
|
5
|
+
from .time.expire import ExpireEvasion
|
|
6
|
+
from .time.utc import UTCEvasion
|
|
7
|
+
from pof.evasion.base import BaseEvasion
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MultiEvasion(BaseEvasion):
|
|
11
|
+
def __init__(self, list_evasion=None) -> None:
|
|
12
|
+
if list_evasion is None:
|
|
13
|
+
list_evasion = [
|
|
14
|
+
CPUCountEvasion(),
|
|
15
|
+
DebuggerEvasion(),
|
|
16
|
+
ExpireEvasion(),
|
|
17
|
+
UTCEvasion(),
|
|
18
|
+
]
|
|
19
|
+
self.list_evasion = list_evasion
|
|
20
|
+
|
|
21
|
+
def import_tokens(self):
|
|
22
|
+
tokens = []
|
|
23
|
+
for evasion in self.list_evasion:
|
|
24
|
+
if len(tokens) > 0:
|
|
25
|
+
tokens.append((NEWLINE, "\n"))
|
|
26
|
+
tokens.extend(evasion.import_tokens())
|
|
27
|
+
return tokens
|
|
28
|
+
|
|
29
|
+
def check_tokens(self):
|
|
30
|
+
tokens = []
|
|
31
|
+
for evasion in self.list_evasion:
|
|
32
|
+
if len(tokens) > 0:
|
|
33
|
+
tokens.append((OP, "or"))
|
|
34
|
+
tokens.extend(
|
|
35
|
+
[
|
|
36
|
+
(OP, "("),
|
|
37
|
+
*evasion.check_tokens(),
|
|
38
|
+
(OP, ")"),
|
|
39
|
+
],
|
|
40
|
+
)
|
|
41
|
+
return tokens
|
|
File without changes
|