Herkese hayırlı sabahlar bugün sizlere Python dilinde obfuscation ile py uzantılı dosyaların şifrelenmesi neticesinde korunan kaynak kodların içerisinde bulunan serial bazlı verilerin RAM üzerinde bir imaj alarak metin belgesine döküp içerisinde nasıl düz metin olarak gözüktüğünü göstereceğim. Tüm kodu ele geçiremesek de serial, şifre, kullanıcı adı gibi plain text yani düz metin olarak görülen metinler RAM içerisinde çözülüyor. Biz bu verileri Python ile RAM imajını alıp, metin belgesi içerisine dökerek bulmaya çalışacağız.
Şimdi Python 'da fastapi kütüphanesi ile basit bir local ağ kuralım kendimize & bu ağa istek atınca gelen cevabımız @Suskun 'un şifresi olsun. Yani API URL 'sine doğru parametreyi girdiğimiz zaman @Suskun 'un ne sakladığını bize gösteren açık kaynak bir kod dizini yazalım. Aşağıdaki kod üzerinde komut isteminde curl -X POST "http://localhost:8080/?password=arwenda" yazarsak bize SuskununGizliVerisi cevabını döndürmesi gerekiyor.
Python:
import uvicorn
from fastapi import FastAPI
FLAG = "SuskununGizliVerisi"
app = FastAPI()
@app.post("/")
async def flag(password: str):
print(password)
if password == "arwenda":
return {"message": FLAG}
return {"message": "Login failed"}
if __name__ == "__main__":
uvicorn.run("main:app", host="0.0.0.0", port=8080)
[ GÖRSEL GÖSTERİM ]
Görüldüğü üzere cevabımız başarılı bir şekilde okunuyor ancak @Suskun kardeşimiz çok akıllı böyle ulu orta açık bir şekilde verilerin paylaşılmasını istemiyor ve hemen araştırma yapıyor bir de ne görsün? Aaaaa PyArmor kaynak kod şifreleyici üstelik son sürümleri henüz kırılamadığı için hiçbir şekilde kaynak kodları okunamıyor bunun üzerine @Suskun verilerinin ulu orta yerlerde paylaşım görmemesi için hemen PyArmor 'u pip komutu ile kurup komutunu veriyor & kaynak kodlarını şifreliyor.
Python:
pip install pyarmor
Python:
pyarmor gen main.py
[ GÖRSEL GÖSTERİM ]
Kaynak kodlarını şifreleyen @Suskun heyecanlı artık kimse sakladığı verileri okuyamaz düşüncesinde hemen kaynak kodları şifreli bir şekilde sanal dünyada paylaşıyor. Ama @Suskun 'un unuttuğu bir yer var o da hafıza yani RAM imajının alınınca düz metinlerin açığa çıkması. Biz bu çok gizli verileri ele geçirmek için şifrelenmiş olan py uzantılı dosyayı indirelim & RAM imajını alan bir kod satırı bulalım bunu da ayrı bir uzantıya kaydedelim mesela dump.py.
Python:
import sys
import ctypes
import ctypes.wintypes as wintypes
import os
# ── Win32 sabitleri ──────────────────────────────────────────────────────────
PROCESS_ALL_ACCESS = 0x1F0FFF
MEM_COMMIT = 0x1000
PAGE_NOACCESS = 0x01
PAGE_GUARD = 0x100
# ── MEMORY_BASIC_INFORMATION yapısı ─────────────────────────────────────────
class MEMORY_BASIC_INFORMATION(ctypes.Structure):
_fields_ = [
("BaseAddress", ctypes.c_void_p),
("AllocationBase", ctypes.c_void_p),
("AllocationProtect", wintypes.DWORD),
("RegionSize", ctypes.c_size_t),
("State", wintypes.DWORD),
("Protect", wintypes.DWORD),
("Type", wintypes.DWORD),
]
def is_readable(protect):
"""Bellek bölgesi okunabilir mi?"""
if protect & PAGE_NOACCESS:
return False
if protect & PAGE_GUARD:
return False
return True
def dump_process_memory(pid: int):
kernel32 = ctypes.windll.kernel32
# ── Process'i aç ────────────────────────────────────────────────────────
handle = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, pid)
if not handle:
err = kernel32.GetLastError()
print(f"[HATA] Process açılamadı. PID={pid}, WinError={err}", file=sys.stderr)
print(" Yönetici (Admin) olarak çalıştırdığınızdan emin olun.", file=sys.stderr)
sys.exit(1)
print(f"[+] Process açıldı: PID={pid}")
out_file = f"{pid}.dump"
total_bytes = 0
region_count = 0
skipped = 0
mbi = MEMORY_BASIC_INFORMATION()
mbi_size = ctypes.sizeof(mbi)
address = 0
# 64-bit sistemde max kullanıcı alanı: 0x7FFFFFFFFFFF (128 TB)
max_addr = 0x7FFFFFFFFFFF
with open(out_file, "wb") as out_f:
while address < max_addr:
# Bellek bölgesi bilgisi sorgula
ret = kernel32.VirtualQueryEx(
handle,
ctypes.c_void_p(address),
ctypes.byref(mbi),
mbi_size
)
if not ret:
break # Tarama bitti
region_start = mbi.BaseAddress or 0
region_size = mbi.RegionSize
# Sadece COMMIT'lenmiş ve okunabilir bölgeleri al
if mbi.State == MEM_COMMIT and is_readable(mbi.Protect):
buf = (ctypes.c_char * region_size)()
bytes_read = ctypes.c_size_t(0)
ok = kernel32.ReadProcessMemory(
handle,
ctypes.c_void_p(region_start),
buf,
region_size,
ctypes.byref(bytes_read)
)
if ok and bytes_read.value > 0:
out_f.write(bytes(buf[:bytes_read.value]))
total_bytes += bytes_read.value
region_count += 1
print(f" [OK] {hex(region_start)} - {hex(region_start + bytes_read.value)}"
f" ({bytes_read.value // 1024} KB)")
else:
err = kernel32.GetLastError()
print(f" [SKIP] {hex(region_start)} hata={err}", file=sys.stderr)
skipped += 1
# Sonraki bölgeye geç
address = region_start + region_size
kernel32.CloseHandle(handle)
size_mb = total_bytes / (1024 * 1024)
print(f"\n[+] Tamamlandı!")
print(f" Dosya : {os.path.abspath(out_file)}")
print(f" Toplam : {size_mb:.2f} MB ({total_bytes} byte)")
print(f" Bölge : {region_count} okundu, {skipped} atlandı")
# ── Giriş noktası ────────────────────────────────────────────────────────────
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"Kullanım: python {sys.argv[0]} <PID>", file=sys.stderr)
print(f"Örnek : python {sys.argv[0]} 1234", file=sys.stderr)
sys.exit(1)
try:
target_pid = int(sys.argv[1])
except ValueError:
print("[HATA] PID sayısal bir değer olmalı.", file=sys.stderr)
sys.exit(1)
dump_process_memory(target_pid)
İmajı aldık ama henüz gizli veri içerisinde aramak veya tespit etmek için bunu açmamız lazım operasyonu gerçekleştirmek için bu imajı alınmış dosyanın içeriğini de metin belgesi içerisine dökmemiz gerekiyor, yine ayrı bir py dosyası oluşturup içerisine aşağıdaki kodları girelim. Adını oku.py yaptım.
Python:
import sys
def extract_strings(data, min_len=4):
"""Dump içindeki okunabilir tüm stringleri çıkar (strings komutu gibi)"""
result = []
current = []
offset_start = 0
for i, b in enumerate(data):
if 32 <= b < 127: # Yazdırılabilir ASCII
if not current:
offset_start = i
current.append(chr(b))
else:
if len(current) >= min_len:
result.append((offset_start, "".join(current)))
current = []
if len(current) >= min_len:
result.append((offset_start, "".join(current)))
return result
def search_dump(dump_file, *keywords):
print(f"[+] Dosya okunuyor: {dump_file}\n")
with open(dump_file, "rb") as f:
data = f.read()
print(f"[+] Dosya boyutu: {len(data) / (1024*1024):.2f} MB\n")
# ── 1. Arama modu ────────────────────────────────────────────────────────
if keywords:
print("=" * 60)
print(" ARAMA SONUÇLARI")
print("=" * 60 + "\n")
for keyword in keywords:
encoded = keyword.encode("utf-8")
idx = 0
found = 0
while True:
idx = data.find(encoded, idx)
if idx == -1:
break
start = max(0, idx - 20)
end = min(len(data), idx + len(encoded) + 40)
context = data[start:end]
printable = "".join(chr(b) if 32 <= b < 127 else "." for b in context)
print(f" [BULUNDU] '{keyword}' offset={hex(idx)}")
print(f" Bağlam : {printable}\n")
idx += len(encoded)
found += 1
if found == 0:
print(f" [YOK] '{keyword}' bulunamadı.\n")
# ── 2. Strings modu ──────────────────────────────────────────────────────
print("=" * 60)
print(" DUMP İÇİNDEKİ OKUNABİLİR STRİNGLER")
print("=" * 60 + "\n")
strings = extract_strings(data, min_len=4)
print(f" Toplam {len(strings)} string bulundu.\n")
# Çıktıyı hem ekrana hem dosyaya yaz
out_txt = dump_file.replace(".dump", "_strings.txt")
with open(out_txt, "w", encoding="utf-8", errors="replace") as f:
f.write(f"Kaynak dump : {dump_file}\n")
f.write(f"Toplam : {len(strings)} string\n")
f.write("=" * 60 + "\n\n")
for offset, s in strings:
line = f" {hex(offset):<14} {s}"
print(line)
f.write(line + "\n")
print(f"\n[+] Tüm stringler '{out_txt}' dosyasına kaydedildi.")
if __name__ == "__main__":
if len(sys.argv) < 2:
print(f"Kullanım : python {sys.argv[0]} <dump_dosyası> [kelime1] [kelime2] ...")
print(f"Örnek 1 : python {sys.argv[0]} 4532.dump")
print(f"Örnek 2 : python {sys.argv[0]} 4532.dump password gizliveri")
sys.exit(1)
dump_file = sys.argv[1]
keywords = sys.argv[2:]
search_dump(dump_file, *keywords)
Şimdi şifrelenmiş olan py uzantılı dosyayı cmd 'yi yönetici olarak çalıştıralım & Python üzerinde aktifleştirelim. Daha sonra bunun Görev Yöneticisi Üzerinde hangi ID 'yi barındırdığını öğrenelim.
[ GÖRSEL GÖSTERİM ]
Daha sonra öğrenmiş olduğumuz bu ID ile bir RAM imajı alalım.
[ GÖRSEL GÖSTERİM ]
RAM imajını aldıktan sonra sonu dump ile biten dosyamızı düz metinleri okuyabilmek için metin belgesine dökelim.
[ GÖRSEL GÖSTERİM ]
Artık şifreli olarak görülen tüm düz metinler RAM 'da çözüldüğü için @Suskun 'un bizden saklamaya çalıştığı verileri araştırmaya başlayalım. Bakalım neleri gizlemiş bizden?
[ GÖRSEL GÖSTERİM ]
Yukarıda yazılan imajı metin belgesine dökme kodu içerisinde direkt olarak arama yapabiliyorsunuz.
[ GÖRSEL GÖSTERİM ]
Yukarıda yazılan imajı metin belgesine dökme kodu içerisinde direkt olarak arama yapabiliyorsunuz.
[ GÖRSEL GÖSTERİM ]
Okuduğunuz için teşekkür ederim. Hayırlı sabahlar diliyorum.
Son düzenleme:

