-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathghostcode.py
More file actions
96 lines (80 loc) · 2.74 KB
/
ghostcode.py
File metadata and controls
96 lines (80 loc) · 2.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/usr/bin/env python3
# ghostcode_mid.py — Detects hidden Unicode in Python source files
import sys
zero_width = {
0x200B: "zero width space",
0x200C: "zero width non-joiner",
0x200D: "zero width joiner",
0xFEFF: "zero width no-break space",
0x2060: "word joiner",
}
bidi = {
0x202A: "left-to-right embedding",
0x202B: "right-to-left embedding",
0x202C: "pop directional formatting",
0x202D: "left-to-right override",
0x202E: "right-to-left override",
0x2066: "left-to-right isolate",
0x2067: "right-to-left isolate",
0x2069: "pop directional isolate",
0x200F: "right-to-left mark",
}
homoglyphs = {
'а': ('a', 0x0430),
'е': ('e', 0x0435),
'о': ('o', 0x043E),
'р': ('p', 0x0440),
'с': ('c', 0x0441),
'х': ('x', 0x0445),
'ϲ': ('c', 0x03F2),
'ν': ('v', 0x03BD),
}
risk_keywords = ['if', 'elif', 'while', 'return', 'assert']
security_keywords = ['role', 'admin', 'auth', 'login', 'password', 'user']
def risk_level(line):
line_strip = line.lstrip()
for kw in risk_keywords:
if line_strip.startswith(kw):
return "HIGH"
if '=' in line and not line_strip.startswith('#'):
return "MEDIUM"
return "LOW"
def scan(source, label):
print("\nScanning:", label)
total_issues = 0
lines = source.splitlines()
for lineno, line in enumerate(lines, 1):
level = risk_level(line)
impact = "Hidden Unicode"
if any(w in line.lower() for w in security_keywords):
impact = "Potential authentication bypass"
for col, ch in enumerate(line, 1):
cp = ord(ch)
if cp in zero_width:
print(f"Line {lineno}, Col {col}: {zero_width[cp]} | Risk: {level} | Impact: {impact}")
total_issues += 1
elif cp in bidi:
print(f"Line {lineno}, Col {col}: {bidi[cp]} | Risk: {level} | Impact: {impact}")
total_issues += 1
elif ch in homoglyphs:
latin, codepoint = homoglyphs[ch]
print(f"Line {lineno}, Col {col}: HOMOGLYPH '{ch}' looks like '{latin}' | Risk: {level} | Impact: {impact}")
total_issues += 1
if total_issues == 0:
print("✓ No suspicious Unicode found. Looks clean!")
else:
print(f"⚠ {total_issues} suspicious character(s) found. Review carefully!")
def main():
if len(sys.argv) < 2:
print("Usage: python3 ghostcode_mid.py <file.py>")
sys.exit(1)
path = sys.argv[1]
try:
with open(path, encoding="utf-8") as f:
source = f.read()
except Exception as e:
print("Error reading file:", e)
sys.exit(1)
scan(source, path)
if __name__ == "__main__":
main()