-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsteganography_module.py
More file actions
359 lines (287 loc) · 11.8 KB
/
Copy pathsteganography_module.py
File metadata and controls
359 lines (287 loc) · 11.8 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
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
"""
Steganografi ve Metadata Manipülasyon Modülü
Metadata Sherlock V4 için
"""
from PIL import Image
import piexif
from datetime import datetime
import struct
import numpy as np
from io import BytesIO
class SteganographyAnalyzer:
"""Steganografi analiz ve uygulama sınıfı"""
@staticmethod
def hide_message_lsb(image, message, key=""):
"""LSB metodu ile mesaj gömme"""
# Mesajı binary'e çevir
if key:
# Basit XOR encryption
message = ''.join(chr(ord(c) ^ ord(key[i % len(key)])) for i, c in enumerate(message))
binary_message = ''.join(format(ord(char), '08b') for char in message)
binary_message += '1111111111111110' # Sonlandırma işareti
img_array = np.array(image)
flat = img_array.flatten()
if len(binary_message) > len(flat):
raise ValueError("Mesaj çok uzun!")
# LSB'lere mesajı yerleştir
for i, bit in enumerate(binary_message):
flat[i] = (flat[i] & 0xFE) | int(bit)
stego_img = flat.reshape(img_array.shape)
return Image.fromarray(stego_img.astype('uint8'))
@staticmethod
def extract_message_lsb(image, key=""):
"""LSB metodundan mesaj çıkarma - geliştirilmiş versiyon"""
img_array = np.array(image)
flat = img_array.flatten()
binary_message = ""
for pixel in flat:
binary_message += str(pixel & 1)
# 8'erli gruplara böl
chars = []
for i in range(0, len(binary_message), 8):
byte = binary_message[i:i+8]
if len(byte) < 8:
break
# Sonlandırma işareti kontrolü (16 bit)
if i + 16 <= len(binary_message):
terminator_check = binary_message[i:i+16]
if terminator_check == '1111111111111110':
break
try:
char_value = int(byte, 2)
# Yazdırılabilir ASCII kontrolü (32-126) veya temel karakterler
if 32 <= char_value <= 126 or char_value in [10, 13]: # newline, carriage return
chars.append(chr(char_value))
elif char_value == 0: # NULL karakter - mesaj sonu olabilir
break
else:
# Yazdırılamayan karakter - mesaj bitmiş olabilir
if len(chars) > 10: # Eğer yeterli karakter varsa dur
break
except:
break
message = ''.join(chars)
# Trailing boşlukları temizle
message = message.rstrip('\x00')
# Eğer şifreliyse çöz
if key and message:
try:
decrypted = ''.join(chr(ord(c) ^ ord(key[i % len(key)])) for i, c in enumerate(message))
# Şifrelenmiş mesajın anlamlı olup olmadığını kontrol et
if all(32 <= ord(c) <= 126 or c in '\n\r\t' for c in decrypted):
message = decrypted
except:
pass # Şifre çözme başarısız, orijinal mesajı döndür
return message.strip()
@staticmethod
def detect_steganography(image):
"""Steganografi olasılığını tespit eder"""
img_array = np.array(image)
flat = img_array.flatten()
# LSB analizi - rastgelelik kontrolü
lsb_bits = [pixel & 1 for pixel in flat[:10000]] # İlk 10000 pixel
ones = sum(lsb_bits)
ratio = ones / len(lsb_bits)
# İdeal oran 0.5 olmalı, çok sapma varsa şüpheli
suspicion_score = abs(0.5 - ratio) * 200
findings = {
'suspicious': suspicion_score > 10,
'score': suspicion_score,
'lsb_ratio': ratio,
'analysis': 'Şüpheli' if suspicion_score > 10 else 'Normal'
}
return findings
class MetadataManipulator:
"""EXIF metadata manipülasyon sınıfı"""
@staticmethod
def create_fake_gps(lat, lon, alt=0):
"""Sahte GPS verisi oluşturur"""
def decimal_to_dms(decimal):
degrees = int(abs(decimal))
minutes = int((abs(decimal) - degrees) * 60)
seconds = int(((abs(decimal) - degrees) * 60 - minutes) * 60 * 100)
return [(degrees, 1), (minutes, 1), (seconds, 100)]
lat_ref = 'N' if lat >= 0 else 'S'
lon_ref = 'E' if lon >= 0 else 'W'
gps_ifd = {
piexif.GPSIFD.GPSLatitudeRef: lat_ref,
piexif.GPSIFD.GPSLatitude: decimal_to_dms(lat),
piexif.GPSIFD.GPSLongitudeRef: lon_ref,
piexif.GPSIFD.GPSLongitude: decimal_to_dms(lon),
piexif.GPSIFD.GPSAltitude: (int(alt * 100), 100)
}
return gps_ifd
@staticmethod
def create_fake_camera_data(make="Canon", model="EOS 5D Mark IV", lens="EF24-70mm f/2.8L II USM"):
"""Sahte kamera verisi oluşturur"""
exif_ifd = {
piexif.ExifIFD.LensMake: make.encode(),
piexif.ExifIFD.LensModel: lens.encode(),
piexif.ExifIFD.ISO: 400,
piexif.ExifIFD.FNumber: (28, 10), # f/2.8
piexif.ExifIFD.ExposureTime: (1, 100), # 1/100s
piexif.ExifIFD.FocalLength: (50, 1), # 50mm
}
zeroth_ifd = {
piexif.ImageIFD.Make: make.encode(),
piexif.ImageIFD.Model: model.encode(),
piexif.ImageIFD.Software: b"Adobe Photoshop CC 2024 (Windows)",
}
return zeroth_ifd, exif_ifd
@staticmethod
def inject_metadata(image, gps_data=None, camera_data=None, custom_date=None):
"""Metadata'yı görüntüye enjekte eder"""
# RGBA → RGB dönüşümü (JPEG için gerekli)
if image.mode in ('RGBA', 'LA', 'P'):
# Alpha channel'ı beyaz arkaplan ile birleştir
background = Image.new('RGB', image.size, (255, 255, 255))
if image.mode == 'P':
image = image.convert('RGBA')
background.paste(image, mask=image.split()[-1] if image.mode in ('RGBA', 'LA') else None)
image = background
elif image.mode != 'RGB':
image = image.convert('RGB')
# Mevcut EXIF'i al (varsa)
try:
exif_dict = piexif.load(image.info.get('exif', b''))
except:
exif_dict = {"0th": {}, "Exif": {}, "GPS": {}, "1st": {}}
# GPS ekle
if gps_data:
exif_dict['GPS'] = gps_data
# Kamera verisi ekle
if camera_data:
zeroth_ifd, exif_ifd = camera_data
exif_dict['0th'].update(zeroth_ifd)
exif_dict['Exif'].update(exif_ifd)
# Tarih ekle
if custom_date:
date_str = custom_date.strftime("%Y:%m:%d %H:%M:%S").encode()
exif_dict['0th'][piexif.ImageIFD.DateTime] = date_str
exif_dict['Exif'][piexif.ExifIFD.DateTimeOriginal] = date_str
exif_dict['Exif'][piexif.ExifIFD.DateTimeDigitized] = date_str
# EXIF bytes'a çevir
exif_bytes = piexif.dump(exif_dict)
# Yeni görüntü oluştur
output = BytesIO()
image.save(output, format='JPEG', exif=exif_bytes, quality=95)
output.seek(0)
return output.getvalue()
class StringsAnalyzer:
"""Binary içindeki string'leri analiz eder"""
@staticmethod
def extract_strings(data, min_length=4):
"""Binary data'dan ASCII string'leri çıkarır"""
strings = []
current = ""
for byte in data:
if 32 <= byte <= 126: # Yazdırılabilir ASCII
current += chr(byte)
else:
if len(current) >= min_length:
strings.append(current)
current = ""
if len(current) >= min_length:
strings.append(current)
return strings
@staticmethod
def find_patterns(strings):
"""String'lerde pattern bulur (URL, email, telefon vs.)"""
import re
patterns = {
'urls': [],
'emails': [],
'phones': [],
'ips': [],
'suspicious': []
}
# Regex'ler
url_pattern = r'https?://[^\s<>"{}|\\^`\[\]]+'
email_pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
phone_pattern = r'\b\d{3}[-.]?\d{3}[-.]?\d{4}\b'
ip_pattern = r'\b(?:\d{1,3}\.){3}\d{1,3}\b'
for string in strings:
# URL
urls = re.findall(url_pattern, string)
patterns['urls'].extend(urls)
# Email
emails = re.findall(email_pattern, string)
patterns['emails'].extend(emails)
# Telefon
phones = re.findall(phone_pattern, string)
patterns['phones'].extend(phones)
# IP
ips = re.findall(ip_pattern, string)
patterns['ips'].extend(ips)
# Şüpheli kelimeler
suspicious_keywords = ['password', 'key', 'secret', 'token', 'api', 'admin']
if any(kw in string.lower() for kw in suspicious_keywords):
patterns['suspicious'].append(string)
return patterns
class ThumbnailAnalyzer:
"""EXIF thumbnail analizi"""
@staticmethod
def extract_thumbnail(image):
"""EXIF'ten thumbnail çıkarır"""
try:
exif = image.info.get('exif')
if not exif:
return None
exif_dict = piexif.load(exif)
if '1st' in exif_dict and piexif.ImageIFD.JPEGInterchangeFormat in exif_dict['1st']:
offset = exif_dict['1st'][piexif.ImageIFD.JPEGInterchangeFormat]
length = exif_dict['1st'][piexif.ImageIFD.JPEGInterchangeFormatLength]
thumbnail = exif[offset:offset+length]
return Image.open(BytesIO(thumbnail))
except:
pass
return None
@staticmethod
def compare_with_main(main_image, thumbnail):
"""Ana görsel ile thumbnail'i karşılaştırır"""
if not thumbnail:
return None
# Boyutları karşılaştır
main_size = main_image.size
thumb_size = thumbnail.size
# Histogram karşılaştırma
main_hist = main_image.resize((100, 100)).histogram()
thumb_hist = thumbnail.resize((100, 100)).histogram()
# Korelasyon hesapla (basit benzerlik)
similarity = sum(min(a, b) for a, b in zip(main_hist, thumb_hist)) / sum(main_hist)
return {
'main_size': main_size,
'thumb_size': thumb_size,
'similarity': similarity * 100,
'suspicious': similarity < 0.8 # %80'den düşükse şüpheli
}
class HexAnalyzer:
"""Hex dump ve analiz"""
@staticmethod
def hex_dump(data, length=256, width=16):
"""Hex dump oluşturur"""
lines = []
for i in range(0, min(len(data), length), width):
chunk = data[i:i+width]
hex_part = ' '.join(f'{byte:02x}' for byte in chunk)
ascii_part = ''.join(chr(byte) if 32 <= byte <= 126 else '.' for byte in chunk)
lines.append(f"{i:08x} {hex_part:<{width*3}} {ascii_part}")
return '\n'.join(lines)
@staticmethod
def find_file_signatures(data):
"""Dosya imzalarını arar (magic bytes)"""
signatures = {
b'\xFF\xD8\xFF': 'JPEG',
b'\x89PNG': 'PNG',
b'GIF8': 'GIF',
b'PK\x03\x04': 'ZIP/JAR',
b'%PDF': 'PDF',
b'\x50\x4B\x03\x04': 'ZIP',
b'\x1F\x8B': 'GZIP',
b'BM': 'BMP'
}
found = []
for sig, file_type in signatures.items():
if sig in data[:1000]: # İlk 1KB'ta ara
found.append(file_type)
return found