-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathghostvault.py
More file actions
267 lines (219 loc) · 10.7 KB
/
Copy pathghostvault.py
File metadata and controls
267 lines (219 loc) · 10.7 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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
#!/usr/bin/env python3
import os
import sys
from steg.image_steg import hide_in_image, extract_from_image
from steg.audio_steg import hide_in_audio, extract_from_audio
from utils.validator import validate_file, check_capacity
def print_logo():
"""Display GhostVault logo with colors."""
logo = """
\033[92m ██████ ██ ██ ██████ ███████ ████████ \033[91m██ ██ █████ ██ ██ ██ ████████
\033[92m ██ ██ ██ ██ ██ ███ ██ \033[91m██ ██ ██ ██ ██ ██ ██ ██
\033[92m ██ ███ ███████ ██ ██ ███████ ██ \033[91m██ ██ ███████ ██ ██ ██ ██
\033[92m ██ ██ ██ ██ ██ ██ ██ ██ \033[91m ██ ██ ██ ██ ██ ██ ██ ██
\033[92m ██████ ██ ██ ██████ ███████ ██ \033[91m ████ ██ ██ ██████ ███████ ██
\033[0m
\033[96m Text-based Steganography Tool\033[0m
\033[93m Hide in Plain Sight\033[0m
\033[95m Created by ACT91\033[0m
\033[94m GitHub: https://github.com/ACT91\033[0m
\033[94m Don't Forget To Leave a Star on this Project : https://github.com/ACT91/GhostVault \033[0m
"""
print(logo)
def scan_file(file_path):
"""Scan file to detect if it contains hidden data."""
try:
ext = os.path.splitext(file_path)[1].lower()
if ext in ['.png', '.jpg', '.jpeg']:
message = extract_from_image(file_path)
elif ext == '.wav':
message = extract_from_audio(file_path)
else:
return None, None
if message:
# Try to detect if it's encrypted - check for base64 pattern
try:
import base64
# Try to decode as base64 - if successful and contains binary data, likely encrypted
decoded = base64.b64decode(message)
is_encrypted = len(decoded) > 16 and len(message) > 20
except:
# Check for non-printable characters or base64-like patterns
is_encrypted = any(ord(c) > 127 or (ord(c) < 32 and c not in '\n\r\t') for c in message[:50])
return "text", is_encrypted
return None, None
except:
return None, None
def convert_audio(file_path):
"""Convert MP3 to WAV format."""
try:
from pydub import AudioSegment
# Load MP3 file
audio = AudioSegment.from_mp3(file_path)
# Create output path
dir_path = os.path.dirname(file_path)
filename = os.path.splitext(os.path.basename(file_path))[0]
output_path = os.path.join(dir_path, f"converted_{filename}.wav")
# Export as WAV
audio.export(output_path, format="wav")
return output_path
except ImportError:
print("\033[91mError: pydub library required for conversion. Install with: pip install pydub\033[0m")
return None
except FileNotFoundError:
print("\033[91mError: FFmpeg not found. Please install FFmpeg or use online converter to convert MP3 to WAV\033[0m")
print("\033[93mAlternative: Use an online MP3 to WAV converter and save the file manually\033[0m")
return None
except Exception as e:
print(f"\033[91mConversion failed: {str(e)}\033[0m")
print("\033[93mTip: Use an online converter or audio editing software to convert MP3 to WAV\033[0m")
return None
def hide_menu():
"""Handle hide operations."""
print("\n\033[92m=== HIDE MESSAGE ===\033[0m")
print("1. Hide in Image")
print("2. Hide in Audio")
choice = input("\nSelect option (1-2): ").strip()
if choice not in ['1', '2']:
print("\033[91mInvalid choice!\033[0m")
return
file_path = input("Enter file path: ").strip().strip('"')
if not validate_file(file_path):
# Check if it's an MP3 file for audio option
if choice == '2' and file_path.lower().endswith('.mp3'):
print("\033[93mMP3 format detected. Choose an option:\033[0m")
print("1. Convert to WAV")
print("2. Use another file (.wav)")
convert_choice = input("Select option (1-2): ").strip()
if convert_choice == '1':
print("\033[96mConverting MP3 to WAV...\033[0m")
converted_path = convert_audio(file_path)
if converted_path:
print(f"\033[92mConversion successful: {os.path.basename(converted_path)}\033[0m")
print("\033[96mGo back and use the converted file.\033[0m")
else:
print("\033[93mConversion failed. Please convert manually or use a WAV file.\033[0m")
return
elif convert_choice == '2':
print("\033[96mPlease select a WAV file.\033[0m")
return
print("\033[91mError: Invalid or unsupported file!\033[0m")
return
message = input("Enter secret message: ").strip()
if not check_capacity(file_path, message):
print("\033[91mError: Message too long for the cover file!\033[0m")
return
output_name = input("Enter output filename (without extension): ").strip()
# Get the same extension as input file
input_ext = os.path.splitext(file_path)[1]
output_path = os.path.join(os.path.dirname(file_path), output_name + input_ext)
use_password = input("Use password protection? (y/n) - y=YES & n=NO : ").strip().lower()
password = None
if use_password == 'y':
password = input("Enter password: ").strip()
try:
if choice == '1':
hide_in_image(file_path, message, output_path, password)
else:
hide_in_audio(file_path, message, output_path, password)
print(f"\033[92mMessage successfully hidden in {output_path}\033[0m")
except Exception as e:
print(f"\033[91mError: {str(e)}\033[0m")
def reveal_menu():
"""Handle reveal operations."""
print("\n\033[93m=== REVEAL MESSAGE ===\033[0m")
# Create extracted_messages folder if it doesn't exist
if not os.path.exists("extracted_messages"):
os.makedirs("extracted_messages")
file_path = input("Enter file path to scan: ").strip().strip('"')
if not validate_file(file_path):
print("\033[91mError: Invalid or unsupported file!\033[0m")
return
print("\n\033[96mScanning file...\033[0m")
content_type, is_encrypted = scan_file(file_path)
if not content_type:
print("\033[91mNo hidden message found in this file.\033[0m")
return
print(f"\033[92mHidden content detected: {content_type.upper()}\033[0m")
password = None
if is_encrypted:
print("\033[93mContent appears to be encrypted.\033[0m")
password = input("Enter password (or press Enter to try without): ").strip()
password = password if password else None
print("\n1. Extract Message")
choice = input("Select option (1): ").strip()
if choice != '1':
print("\033[91mInvalid choice!\033[0m")
return
try:
ext = os.path.splitext(file_path)[1].lower()
# First extract raw message without decryption
if ext in ['.png', '.jpg', '.jpeg']:
raw_message = extract_from_image(file_path)
if password:
decrypted_message = extract_from_image(file_path, password)
else:
decrypted_message = raw_message
elif ext == '.wav':
raw_message = extract_from_audio(file_path)
if password:
decrypted_message = extract_from_audio(file_path, password)
else:
decrypted_message = raw_message
if raw_message:
# Show encrypted message first if password was used
if password and raw_message != decrypted_message:
print(f"\n\033[93mEncrypted message:\033[0m")
print(f"\033[96m{raw_message}\033[0m")
reveal_option = input("\nReveal decrypted message? (y/n): ").strip().lower()
if reveal_option == 'y':
print(f"\n\033[92mDecrypted message:\033[0m")
print(f"\033[96m{decrypted_message}\033[0m")
message = decrypted_message
else:
message = raw_message
else:
print(f"\n\033[92mExtracted message:\033[0m")
print(f"\033[96m{decrypted_message}\033[0m")
message = decrypted_message
save_option = input("\nSave to file? (y/n): ").strip().lower()
if save_option == 'y':
# Create extracted_messages folder if it doesn't exist
output_dir = "extracted_messages"
if not os.path.exists(output_dir):
os.makedirs(output_dir)
output_name = input("Enter output filename (without extension): ").strip()
output_file = os.path.join(output_dir, output_name + ".txt")
with open(output_file, 'w', encoding='utf-8') as f:
f.write(message)
print(f"\033[92mMessage saved to {output_file}\033[0m")
else:
print("\033[91mFailed to extract message. Check password or file integrity.\033[0m")
except Exception as e:
print(f"\033[91mError: {str(e)}\033[0m")
def main():
"""Main program loop."""
while True:
print_logo()
print("\n\033[96m=== MAIN MENU ===\033[0m")
print("1. Hide Me")
print("2. Reveal Me")
print("3. Exit")
choice = input("\nSelect option (1-3): ").strip()
if choice == '1':
hide_menu()
elif choice == '2':
reveal_menu()
elif choice == '3':
print("\n\033[93mThank you for using GhostVault! 👻\033[0m")
sys.exit(0)
else:
print("\033[91mInvalid choice! Please select 1, 2, or 3.\033[0m")
input("\nPress Enter to continue...")
os.system('cls' if os.name == 'nt' else 'clear')
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print("\n\n\033[93mGoodbye! 👻\033[0m")
sys.exit(0)