برچسب: With

  • Threat Actors are Targeting US Tax-Session with new Tactics of Stealerium-infostealer

    Threat Actors are Targeting US Tax-Session with new Tactics of Stealerium-infostealer


    Introduction

    A security researcher from Seqrite Labs has uncovered a malicious campaign targeting U.S. citizens as Tax Day approaches on April 15. Seqrite Labs has identified multiple phishing attacks leveraging tax-related themes as a vector for social engineering, aiming to exfiltrate user credentials and deploy malware. These campaigns predominantly utilize redirection techniques, such as phishing emails, and exploit malicious LNK files to further their objectives.

    Each year, cybercriminals exploit the tax season as an opportunity to deploy various social engineering tactics to compromise sensitive personal and financial data. These adversaries craft highly deceptive campaigns designed to trick taxpayers into divulging confidential information, making fraudulent to counterfeit services, or inadvertently installing malicious payloads on their devices, thereby exposing them to identity theft and financial loss.

    Infection Chain:

    Fig 1: Infection chain

    Initial analysis about campaign:

    While tax-season phishing, attacks pose a risk to a broad spectrum of individuals, our analysis indicates that certain demographics are disproportionately vulnerable. Specifically, high-risk targets include individuals with limited knowledge of government tax processes, such as green card holders, small business owners, and new taxpayers.

    Our findings reveal that threat actors are leveraging a sophisticated phishing technique in which they deliver files via email with deceptive extensions. One such example is a file named “104842599782-4.pdf.lnk,” which utilizes a malicious LNK extension. This tactic exploits user trust by masquerading as a legiti payments mate document, ultimately leading to the execution of malicious payloads upon interaction.

    Decoy Document:

    Threat actors are disseminating a transcript related to tax sessions, targeting individuals through email by sharing it as a malicious attachment. These cybercriminals are leveraging this document as a vector to deliver harmful payloads, thereby compromising the security of the recipients.

     

    Fig 2: Decoy Document

    Technical Analysis:

    We have retrieved the LNK file, identified as “04842599782-4.pdf.lnk,” which was utilized in the attack. This LNK file embeds a Base64-encoded payload within its structure.

    Fig 3: Inside LNK File

    Upon decoding the string, we extracted a PowerShell command line that itself contains another Base64-encoded payload embedded within it.

    Fig 4: Encoded PowerShell Command Line

     

    Subsequently, upon decoding the nested Base64 string, we uncovered the final PowerShell command line embedded within the payload.

    Fig 5: Decoded Command Line

    The extracted PowerShell command line initiated the download of rev_pf2_yas.txt, which itself is a PowerShell script (Payload.ps1) containing yet another Base64-encoded payload embedded within it.

    Fig 6: 2nd PowerShell command with Base64 Encoded

    We have decoded the above Base64 encoded command line and get below final executable.

    Fig 7: Decoded PowerShell Command

    According to the PowerShell command line, the script Payload.ps1 (or rev_pf2_yas.txt) initiated the download of an additional file, revolaomt.rar, from the Command and Control (C2) server. This archive contained a malicious executable, named either Setup.exe or revolaomt.exe.

    Detail analysis of Setup.exe / revolaomt.exe:

    Fig 8: Detect it Easy

    Upon detailed examination of the Setup.exe binary, it was identified as a PyInstaller-packaged Python executable. Subsequent extraction and decompilation revealed embedded Python bytecode artifacts, including DCTYKS.pyc and additional Python module components.

    Fig 9: PyInstaller-packaged Python executable
    Fig 10: In side DCTYKS.pyc

    Upon analysis of the DCTYKS.pyc sample, it was determined that the file contains obfuscated or encrypted payload data, which is programmatically decrypted at runtime and subsequently executed, as illustrated in the figure above.

    Fig 11: Encoded DCTYKS.pyc with Base64

    Upon successful decryption of the script, it was observed that the sample embeds a Base64-encoded executable payload. The decrypted payload leverages process injection techniques to target mstsc.exe for execution. Further analysis of the second-stage payload revealed it to be a .NET-compiled binary.

    Analysis 2nd Payload (Stealerium malware):

    Fig 12: .NET Base Malware sample

    The second-stage payload is identified as a .NET-based malware sample. Upon inspection of its class structures, methods, and overall functionality, the sample exhibits strong behavioural and structural similarities to the Stealerium malware family, specifically aligning with version 1.0.35.

    Stealerium is an open-source information-stealing malware designed to exfiltrate sensitive data from web browsers, cryptocurrency wallets, and popular applications such as Discord, Steam, and Telegram. It performs extensive system reconnaissance by harvesting details including active processes, desktop screenshots, and available Wi-Fi network configurations. Additionally, the malware incorporates sophisticated anti-analysis mechanisms to identify execution within virtualized environments and detect the presence of debugging tools.

    Anti_Analysis

    Fig 13: Anti Analysis Techniques
    Fig 14: GitHub URLs
    Fig 15: Detecting Suspicious ENV

    This AntiAnalysis class is part of malware designed to detect sandbox, virtual machines, emulators, suspicious processes, services, usernames, and more. It checks system attributes against blacklists fetched from online sources (github). If any suspicious environment is detected, it logs the finding and may trigger self-destruction. This helps the malware avoid analysis in controlled or security research setups.

    Mutex Creation

    Fig 16: Mutex Creation

    This MutexControl class prevents multiple instances of the malware from running at the same time. It tries to create a system-wide mutex using a name from Config.Mutex (QT1bm11ocWPx). If the mutex already exists, it means another instance is running, so it exits the process. If an error occurs during this check, it logs the error and exits too.

    Fig 17: Configuration of StringsCrypt.DecryptConfig

    It configures necessary values by decrypting them with StringsCrypt.DecryptConfig. It handles the decryption of the server base URL and WebSocket address. If enabled, it also decodes cryptocurrency wallet addresses from Base64 and decrypts them using AES-256 encryption.

    “hxxp://91.211.249.142:7816”

    Radom Directory Creation

    Fig 18: Random Directory Creation

    The InitWorkDir() method generates a random subdirectory under %LOCALAPPDATA%, creates it if it doesn’t exist, and hides it for stealth purposes. This is likely used for storing data or maintaining persistence without detection.

    \AppData\Local\e9d3e2dd2788c322ffd2c9defddf7728 random directory is created in hidden attribute.

    BoT Registration

    Fig 19: BOT Registration

    The RegisterBot method initiates an HTTP POST request to register a bot instance, utilizing a unique hash identifier and an authorization token for authentication. It serializes the registration payload, appends the necessary HTTP headers, and logs the server response or any encountered exceptions. The method returns a boolean value—true upon successful execution, and false if an exception is raised during the process.

    RequestUri: ‘http[:]//91[.]211[.]249[.]142:7816/api/bot/v1/register’

     

    Stealer Activity From Browser:

    Fig 20: Stealer activity from Browser

    It extracts browser-related data (passwords, cookies, credit cards, history, bookmarks, autofill) from a given user data profile path.

    FileZilla Credentials stealer activity

    Fig 21: FileZilla Credential Stealer activity

    The above code is part of a password-stealing component targeting FileZilla, an FTP client.

    Gaming Platform Data Extraction Modules

    Fig 22: Gaming platform data extraction

    This component under bt.Stub.Target.Gaming is designed to collect data from the following platforms:

    • BattleNet
    • Minecraft
    • Steam
    • Uplay

    Each class likely implements routines to extract user data, game configurations, or sensitive files for exfiltration.

    Fig 23: Checks for a Minecraft installation

    It checks for a Minecraft installation and creates a save directory to exfiltrate various data like mods, files, versions, logs, and screenshots. It conditionally captures logs and screenshots based on the Config.GrabberModule setting.

    Messenger Data Stealer Modules

    Itargets various communication platforms to extract user data or credentials from:

    • Discord
    • Element
    • ICQ
    • Outlook
    • Pidgin
    • Signal
    • Skype
    • Telegram
    • Tox

    Below is one example of Outlook Credentials Harvesting

    It targets specific registry keys associated with Outlook profiles to extract sensitive information like email addresses, server names, usernames, and passwords. It gathers data for multiple mail clients (SMTP, POP3, IMAP) and writes the collected information to a file (Outlook.txt).

    Fig 24: Messenger Data Extraction

     

    Webcam Screenshot Capture

    Attempts to take a screenshot using a connected webcam, saving the image as a JPEG file. If only one camera is connected, it triggers a series of messages to capture the webcam image, which is then saved to the specified path (camera.jpg or a timestamped filename). The method is controlled by a configuration setting (Config.WebcamScreenshot).

     

    Fig 25: Webcam Screen shot captures

     

    Wi-Fi Password Retrieval

     

    It retrieves the Wi-Fi password for a given network profile by running the command netsh wlan show profile and extracting the password from the output. The command uses findstr Key to filter the password, which is then split and trimmed to get the value

     

    Fig 26: WI-FI Password Retrieval

     

    VPN Data Extraction

    It targets various VPN applications to exfiltrate sensitive information such as login credentials:

    • NordVpn
    • OpenVpn
    • ProtonVpn

    For example, it  extracts and saves NordVPN credentials from the user.config file found in NordVPN installation directories. It looks for “Username” and “Password” settings, decodes them, and writes them to a file (accounts.txt) in the specified savePath.

     

    Fig 27: VPN Data Extraction

     

    Porn Detection & Screenshot Capture

    Fig 28: Porn Detection & Snapshot Captures.

    It detects adult content by checking if the active window’s title contains specific keywords related to NSFW content (configured in Config.PornServices). If such content is detected, it triggers a screenshot capture.

    Conclusion:

    Based on our recent proactive threat analysis, we’ve identified that cybercriminals are actively targeting U.S. citizens around the tax filing period scheduled for April 15. These threat actors are leveraging the occasion to deploy Stealerium malware, using deceptive tactics to trick users.

    Stealerium malware is designed to steal Personally Identifiable Information (PII) from infected devices and transmit it to attacker-controlled bots for further exploitation.

    To safeguard your data and devices, we strongly recommend using Seqrite Endpoint Security, which provides advanced protection against such evolving threats.

    Stay secure. Stay protected with Seqrite.

    TTPS

    Tactic Technique ID Name
    Initial Access T1566.001 Phishing: Spear phishing Attachment
    Execution T1059.001 Command and Scripting Interpreter: PowerShell
    Evasion T1140 Deobfuscate/Decode Files or Information
    T1027 Obfuscated Files or Information
    T1497 Virtualization/Sandbox Evasion
    T1497.001 System Checks
    Credential Access T1555.003 Credentials from Password Stores:  Credentials from Web Browsers

     

    T1539 Steal Web Session Cookie
    Discovery T1217 Browser Information Discovery
    T1016 System Network Configuration Discovery: Wi-Fi Discovery
    Collection T1113 Screen Capture
    Exfiltration T1567.004 Exfiltration Over Web Service:  Exfiltration Over Webhook

     

    Seqrite Protections:

    • HEUR:Trojan.Win32.PH
    • Trojan.49490.GC
    • trojan.49489.GC

    IoCs:

    File Name SHA-256
    Setup.exe/revolaomt.exe 6a9889fee93128a9cdcb93d35a2fec9c6127905d14c0ceed14f5f1c4f58542b8
    104842599782-4.pdf.lnk 48328ce3a4b2c2413acb87a4d1f8c3b7238db826f313a25173ad5ad34632d9d7
    payload_1.ps1 / fgrsdt_rev_hx4_ln_x.txt 10f217c72f62aed40957c438b865f0bcebc7e42a5e947051edee1649adf0cbf2
    revolaomt.rar 31705d906058e7324027e65ce7f4f7a30bcf6c30571aa3f020e91678a22a835a
    104842599782-4.html Ff5e3e3bf67d292c73491fab0d94533a712c2935bb4a9135546ca4a416ba8ca1

     

    C2:

    • hxxp[:]//91[.]211[.]249[.]142:7816/
    • hxxp://91.211.249.142:7816″
    • hxxp[:]//185[.]237[.]165[.]230/

     

    Authors:

    Dixit Panchal
    Kartik Jivani
    Soumen Burma



    Source link

  • How To Convert A List To A String In Python (With Examples)



    How To Convert A List To A String In Python (With Examples)



    Source link

  • JavaScript Location.reload() Explained (With Examples)

    JavaScript Location.reload() Explained (With Examples)


    In modern web development, there are times when a page needs to refresh itself without the user pressing a button. Whether you are responding to updated content, clearing form inputs, or forcing a session reset, JavaScript provides a simple method for this task: location.reload().

    This built-in method belongs to the window.location object and allows developers to programmatically reload the current web page. It is a concise and effective way to refresh a page under controlled conditions, without relying on user interaction.

    What Is JavaScript location.reload()?

    The location.reload() method refreshes the page it is called on. In essence, it behaves the same way a user would if they clicked the browser’s reload button. However, because it is called with JavaScript, the action can be triggered automatically or in response to specific events. 

    Here is the most basic usage:

    location.reload();

    This line of code tells the browser to reload the current page. It does not require any parameters by default and typically loads the page from the browser’s cache. Note that you can use our free resources (namely, online code editors) to follow along with this discussion.

    Forcing a Hard Reload

    Sometimes a regular reload is not enough, especially when you want to ensure that the browser fetches the latest version of the file from the server instead of using the cached copy. You can force a hard reload by passing true as a parameter:

    location.reload(true);

    However, it is important to note that modern browsers have deprecated this parameter in many cases. Instead, they treat all reloads the same. If you need to fully bypass the cache, server-side headers or a versioned URL might be a more reliable approach.

    And let’s talk syntax:

    So what about the false parameter? That reloads the page using the web browser cache. Note that false is also the default parameter. So if you run reload() without a parameter, you’re actually running object.reload(false). This is covered in the Mozilla developer docs.

    So when do you use Location.reload(true)? One common situation is when the page has outdated information. A hard reload can also bypass caching issues on the client side.

    Common Use Cases

    The location.reload() method is used across a wide range of situations. Here are a few specific scenarios where it’s especially useful:

    1. Reload after a form submission:

    document.getElementById("myForm").onsubmit = function() {
        setTimeout(function() {
            location.reload();
        }, 1000);
    };

    This use case helps clear form inputs or reset the page state after the form has been processed. You can test this in the online Javascript editor. No download required. Just enter the code and click run to immediately see how it looks.

    2. Refresh after receiving new data:

    In web applications that rely on live data, such as dashboards or status monitors, developers might use location.reload() to ensure the page displays the most current information after an update.

    3. Making a manual refresh button:

    <button onclick="location.reload();">Refresh Page</button>

    This is a simple way to give users control over when to reload, particularly in apps that fetch new content periodically.

    4. Reload a Page Without Keeping the Current Page in Session History

    This is another common use. It looks like this.

    window.location.replace(window.location.href);

    Basically, if a user presses the back button after they hit reload, they might be taken back to a page that no longer reflects the current application logic. The widow.location.replace() method navigates to a new URL, often the same one, and replaces the current page in the session history.

    This effectively reloads the page without leaving a trace in the user’s history stack. It is particularly useful for login redirects, post-submission screens, or any scenario where you want to reset the page without allowing users to revisit the previous state using the back button.

    Limitations and Best Practices

    While location.reload() is useful; it should be used thoughtfully. Frequent or automatic reloads can frustrate users, especially if they disrupt input or navigation. In modern development, reloading an entire page is sometimes considered a heavy-handed approach.

    For dynamic updates, using JavaScript to update only part of the page, through DOM manipulation or asynchronous fetch requests, is often more efficient and user-friendly.

    Also, keep in mind that reloading clears unsaved user input and resets page state. It can also cause data to be resubmitted if the page was loaded through a form POST, which may trigger browser warnings or duplicate actions. If you’re looking for a job, make sure to brush up on this and any other common JavaScript interview questions.

    Smarter Alternatives to Reloading the Page

    While location.reload() is simple and effective, it is often more efficient to update only part of a page rather than reloading the entire thing. Reloading can interrupt the user experience, clear form inputs, and lead to unnecessary data usage. In many cases, developers turn to asynchronous techniques that allow content to be refreshed behind the scenes.

    AJAX, which stands for Asynchronous JavaScript and XML, was one of the earliest ways to perform background data transfers without refreshing the page. It allows a web page to send or receive data from a server and update only the necessary parts of the interface. Although the term AJAX often brings to mind older syntax and XML data formats, the concept remains vital and is now commonly used with JSON and modern JavaScript methods.

    One of the most popular modern approaches is the Fetch API. Introduced as a cleaner and more flexible alternative to XMLHttpRequest, the Fetch API uses promises to handle asynchronous requests. It allows developers to retrieve or send data from a server and then apply those updates directly to the page using the Document Object Model, or DOM.

    Here is a simple example:

    fetch('/api/data')
      .then(response => response.json())
      .then(data => {
        document.getElementById('content').textContent = data.message;
      });

    This example retrieves data from the server and updates only a single element on the page. It is fast, efficient, and keeps the user interface responsive.

    By using AJAX or the Fetch API, developers can create a more fluid and interactive experience. These tools allow for partial updates, background syncing, and real-time features without forcing users to wait for an entire page to reload. In a world where performance and responsiveness matter more than ever, these alternatives offer a more refined approach to managing content updates on the web.

    Conclusion

    The location.reload() method in JavaScript is a straightforward way to refresh the current web page. Whether used for resetting the interface or updating content, it offers a quick and accessible solution for common front-end challenges. But like all tools in web development, it should be used with an understanding of its impact on user experience.

    Before reaching for a full page reload, consider whether updating the page’s content directly might serve your users better. When applied appropriately, location.reload() can be a useful addition to your JavaScript toolkit.

    Want to put this into action? Add it to a JavaScript project and test it out.

     





    Source link

  • HTML Editor Online with Instant Preview and Zero Setup



    HTML Editor Online with Instant Preview and Zero Setup



    Source link

  • Write and Test Code Instantly With an Online Python Editor



    Write and Test Code Instantly With an Online Python Editor



    Source link

  • Kimsuky APT Targets South Korea with Deceptive PDF Lures

    Kimsuky APT Targets South Korea with Deceptive PDF Lures


    Kimsuky: A Continuous Threat to South Korea with Deceptive Tactics

    Contents

    • Introduction
    • Infection Chain
    • Initial Findings
    • Campaign 1
      • Looking into PDF document.
    • Campaign 2
      • Looking into PDF document.
    • Technical Analysis
    • Conclusion
    • Seqrite Protection
    • MITRE ATT&CK
    • IOCs

    Introduction:

    Security researchers at Seqrite Labs have recently uncovered two distinct campaigns carried out by the APT group “Kimsuky,” also known as “Black Banshee.” This group has been actively targeting South Korea using evolving tactics. In these campaigns, the threat actors delivered two South Korean government-themed documents as lures, specifically targeting government entities within South Korea.

    In this blog, we will delve into the technical details of the campaigns uncovered during our analysis. We will examine the various stages of infection, starting with a phishing email containing an LNK (shortcut) file attachment. The LNK file was designed to drop an obfuscated VBA (Visual Basic for Applications) script, After de-obfuscating the script, we found that it was responsible for dropping two additional files: One Pdf file and One ZIP file The ZIP file contained four malicious files: two log files (1.log and 2.log), one VBA script (1.vba), and one PowerShell script (1.ps1). Both campaigns involved the same set of malicious files.

    Infection Chain:

    Fig .1 infection chain

    Initial Findings:

    Campaign-1:

    In the first campaign, we identified a document related to tax reduction and tax payment related to revenue, which contained the same malicious LNK attachment. This attachment subsequently deployed a malicious VBScript, facilitating further compromise.

     

    Fig .2 Revanue.pdf file

     

    Based on our initial findings, we discovered that the adversary utilized a different document containing the same LNK file content.

    Campaign-2:

    In campaign-2, it has come to our attention that South Korea has enacted a new policy aimed at preventing recidivism among sex offenders. The initiative involves circulating a detailed document outlining the regulations, which was shared with households, daycare centers, kindergartens, and various local administrative offices, including township and village authorities, as well as neighbourhood community centres. However, hackers, including cyber-criminals, are exploiting this dissemination process by sending deceptive emails containing harmful attachments. These emails are targeting residential recipients and key personnel at local offices.

     

    Fig .3 Sex Offender Personal Information Notification.pdf

     

    The adversaries have exploited the distribution of this information and document by circulating it via email, disguised under the filename 성범죄자 신상정보 고지.pdf.lnk (Sex Offender Personal Information Notification.pdf.lnk). This attachment contains a malicious LNK file, which poses a cybersecurity threat to the recipients.

     

    Technical Analysis and Methodology:

    Campaign 1 & 2:

    We have downloaded the file named 28f2fcece68822c38e72310c911ef007f8bd8fd711f2080844f666b7f371e9e1.lnk from campaign-1 and “성범죄자 신상정보 고지.pdf.lnk” from campaign-2 (Sex Offender Personal Information Notification.pdf.lnk) that was shared via email. During the analysis of this LNK file, it appears to be fetching additional files from an external C2 server, as shown in the snapshot below.

    Fig.4 Downloading VBScript from C2 (Campaign –1)

     

    Fig .5 Downloading VBScript From C2 (Campaign -2)

    The file was downloaded from the URL provided above and saved into the Temp folder, as indicated below.

    Fig .6 downloaded into Temp Folder (Campaign-1)

     

    Fig .7 downloaded into Temp Folder (Campaign-2)

    The file downloaded from the C2 server appears to be an obfuscated VBScript. Upon DE obfuscating the script, we discovered two additional files: one PDF and one ZIP file.

    Fig .8 Obfuscated VB Script

    The first section of the file is encoded in Base64 strings.

    Fig .9 Base64 Encoded PDF

    After Decoding we have found one PDF file.

     

    Fig .10 PDF after Decoding

     

    The second part of the VBScript is also encoded in Base64. After decoding it, we discovered a ZIP file.

    Fig .11 Zip File

     

    Fig. 12 Detect It Easy

    Zip files contain the below numbers of files in it.

    Fig .13 Inside Zip File

    Within the ZIP archive, four files were identified: a VBScript, a PowerShell script, and two Base64-encoded text files. These encoded text files house obfuscated data, which, upon further dissection, may yield critical intelligence regarding the malware’s functionality and objectives. The following figures illustrate the encoded content of the two text files, which will be subsequently decoded and analysed to elucidate the next phase in the attack chain.

    Fig. 14- 1 Log.txt file with Base64 encoding

     

    Fig.15 – 2 Log .txt file with Base64 encoding

    The 1.vbs file employs advanced obfuscation techniques, utilizing the chr() and CLng() functions to dynamically construct characters and invoke commands at runtime. This strategy effectively circumvents signature-based detection mechanisms, allowing the script to evade detection during execution.

    Upon script termination, the concatenated characters form a complete command, which is subsequently executed. This command is likely designed to invoke the 1.ps1 PowerShell script, passing 1.log as an argument for further processing.

    Fig .16 – 1.vbs

    Upon attempting to DE-obfuscate the VBScript, we uncovered the following command-line execution, which subsequently triggers the PowerShell script for further processing.

    Fig .17  De-Obfuscated VB Script

    Upon executing the 1.vbs file, it triggered the invocation of the 1.ps1 file, as illustrated in the snapshot below.

    Fig .18 Executing 1.VBS

    The 1.ps1 script includes a function designed to decode Base64-encoded data from the 1.log file and execute the resulting script.

    Fig.19 – 1.ps1 file

     

    Fig.20 – 1 Log.txt after decoding

    The 1.ps1 script retrieves the BIOS serial number, a unique system identifier, from the compromised host. This serial number is subsequently used to create a dedicated directory within the system’s temporary folder, ensuring that attack-related files are stored in a location specific to the compromised machine, as shown in above snapshot.

    As a VM-aware sample, the script checks if it is executing within a virtual machine environment. If it detects a virtual machine, it will delete all four files associated with the attack (1.vbs, 1.ps1, 1.log, and any payload files stored in the directory named after the serial number), effectively halting its execution, as illustrated.

    The script encompasses 11 functions that define the subsequent phases of the malware’s operation, which include data exfiltration, cryptocurrency wallet information theft, and the establishment of Command-and-Control (C2) communications. These functions are integral to the attack’s execution, facilitating the malware’s objectives and ensuring persistent communication with the threat actor.

    List of malicious function retrieved from 1 log file:

    1. UploadFile ():

    The upload function exfiltrates data by transmitting it to the server in 1MB chunks, allowing it to handle large file sizes efficiently. The script awaits a response from the server, and if it receives an HTTP status code of “200,” it proceeds with further execution. If the response differs, the script terminates its operation. Each chunk is sent via an HTTP POST request, with the function verifying the success of each upload iteration before continuing.

    Fig .21 UploadFile()

     

    1. GetExWFile ():

    The GetExWFile function iterates through a set of predefined hash tables containing cryptocurrency wallet extensions. When a match is found, it identifies the associated”.ldb” and ”.log” files linked to those extensions for exfiltration. These files are subsequently transferred to the specified destination folder, as indicated by the $Storepath variable.

    Fig.22 GetExWFile ()
    1. GetBrowserData ():

    The script checks whether any of the following browsers—Edge, Firefox, Chrome, or Naver Whale—are actively running, to extract user profile data, including cookies, login credentials, bookmarks, and web data. Prior to collecting this information, the script terminates the browser processes to ensure uninterrupted access. It then proceeds to retrieve data on installed extensions and cache files, such as webcacheV01.dat, for each identified browser. For certain browsers, it also performs decryption operations to unlock encrypted keys, allowing it to extract sensitive information, which is then stored alongside the decrypted master encryption key.

    Fig.23 BrowserData ()
    1. Download file () :

    The download file function downloads any file based on the C2 command.

    Fig.24 Download File ()
    1. RegisterTask () :

    It creates persistence for the files “1.log” and “1.vbs”.

    Fig.25 RegisterTask()
    1. Send ():

    The send () function uploads all the collected information to the server after compressing the data into a ZIP file named “init.zip”. It then renames the ZIP file to “init.dat” and deletes all backup files from the system after uploading.

    Fig.26 Send ()

    The execution flow of the functions follows a sequence where several actions are carried out within the attack. Among these functions, one triggers another PowerShell command that calls the 2.log file, which is responsible for performing keylogging activities.

     

    Fig. 27 Flow of execution of functions and command to execute “2.log”.
    Fig.28 Executing 2 log file

     

    Fig.29 Inside 2 log file

     

    The decoded content of the 2.log file is shown above. It contains a script that imports essential Windows API functions for detecting key presses, retrieving window titles, and managing keyboard states. The script executes actions such as clipboard monitoring, keystroke logging, and recording window titles.

    Fig. 30.2 Code for clipboard monitoring.

    Conclusion

    As observed, threat actors are utilizing time-consuming, multi-component techniques that are interlinked to enhance their evasiveness. Unlike other stealers, this one primarily focuses on network-related information, which could be leveraged for active reconnaissance. Given that the stealer targets sensitive user data, it is crucial to protect yourself with a reputable security solution such as Seqrite Antivirus in today’s digital landscape. At Seqrite Lab, we provide detection capabilities for such stealers at various stages of infection, along with protection against the latest threats.

    Seqrite Protection:

    • Trojan.49424.SL
    • Trojan.49422.C

     

    MITRE ATT&CK:

    Initial Access T1566.001 Phishing: Spearphishing Attachment
    Execution T1059.001

     

    T1059.005

    Command and Scripting Interpreter: PowerShell

    Command and Scripting Interpreter: Visual Basic

    Persistence T1547.001 Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder
    Defense Evasion T1140 Deobfuscate/Decode Files or Information
    Credential Access T1555.003 Credentials from Password Stores: Credentials from Web Browsers
    Discovery T1082 System Information Discovery
    Collection T1056.001 Input Capture: Keylogging
    Command and Control T1071.001 Application Layer Protocol: Web Protocols
    Exfiltration T1041 Exfiltration Over C2 Channel

    IoCs:

    MD5  File Name
    1119A977A925CA17B554DCED2CBABD8  *.lnk
    64677CAE14A2EC4D393A81548417B61B  1.log
    F0F63808E17994E91FD397E3A54A80CB  2.log
    A3353EA094F45915408065D03AE157C4  prevenue.hta
    CE4549607E46E656D8E019624D5036C1  1.vbs
    1B90EFF0B4F54DA72B19195489C3AF6C  *.lnk
    1D64508B384E928046887DD9CB32C2AC 성범죄자 신상정보 고지.pdf.lnk

    C2

    • hxxps[:]//cdn[.]glitch[.]global/
    • hxxp[:]//srvdown[.]ddns.net

     

    Authors

    Dixit Panchal

    Kartik Jivani

    Soumen Burma

     

     



    Source link

  • Mastering Carousels with GSAP: From Basics to Advanced Animation

    Mastering Carousels with GSAP: From Basics to Advanced Animation


    Carousels are a fairly common UI pattern (there are many excellent carousel and slider examples available on Codrops). While carousel designs vary depending on the use case, the following demos explore how the GreenSock Animation Platform (GSAP) can be used to achieve seamless looping, smooth animations, and ultimately, a better user experience.

    This article is for frontend designers and developers interested in enhancing the functionality and visual appeal of a standard horizontal carousel. Familiarity with JavaScript and basic GSAP methods will be helpful, but anyone looking for inspiration and practical examples may find the following content useful.

    What You’ll Learn

    • Basic carousel implementation using HTML and CSS
    • How to use gsap.utils.wrap() and horizontalLoop()
    • Advanced animation techniques, including image parallax and function-based values

    Our Basic Carousel

    Let’s start with a horizontally scrolling carousel using only HTML and CSS:

    <div class="carousel">
        
        <div class="carousel-slide">
          <img src="https://images.unsplash.com/photo-1659733582156-d2a11801e59f?q=50&w=1600">
          <h2>We're No</h2>
          <h5>Strangers to love</h5>
        </div>
            
        ...
    
    </div>
    .carousel {
      width: 100vw;
      height: 80vh;
      gap: 10px;
      overflow-x: auto;
      scroll-snap-type: x mandatory;
      display: flex;
      -webkit-overflow-scrolling: touch;
    }
    
    .carousel-slide {
      position: relative;
      flex: 0 0 50%;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      color: white;
      scroll-snap-align: center;
      overflow: hidden;
    }
    
    .carousel-slide img {
      position: absolute;
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
    
    h2 {
      position: relative;
      margin: 0;
      font-size: 1.8rem;
    }
    
    h5 {
      position: relative;
      margin: 2% 0 0 0;
      font-size: 1rem;
      font-weight: 100;
      letter-spacing: 0.3px;
    }
    
    /* Simplify the scroll bar appearance */
    ::-webkit-scrollbar {
      height: 13px;
    }
    
    ::-webkit-scrollbar-track {
      background: transparent;
    }
    
    ::-webkit-scrollbar-thumb {
      border-top: 6px solid #000;
      background: #555;
      width: 50%;
    }
    
    ::-webkit-scrollbar-thumb:hover {
      background: #bbb;
    }
    
    @media (max-width: 500px) {
      .carousel-slide {
        flex: 0 0 80%;
      }
    
      ::-webkit-scrollbar-thumb {
        width: 80%;
      }
    }

    Here’s the result:

    It uses scroll snapping and some custom styling on the scrollbar. Nothing fancy, but it works even when JavaScript is disabled.

    Note that the HTML above is intentionally concise. However, in production, it’s important to follow accessibility best practices, including using alt text on images and descriptive ARIA attributes for screen reader users.

    Building on the Foundation – GSAP Demo 1A

    To see how GSAP can enhance a carousel, we’ll explore two different approaches—the first using gsap.utils.wrap(). Wrap is one of several handy utility methods included in gsap.js—no plugin required! Given a min/max range, it returns a value within that range:

     gsap.utils.wrap(5, 10, 12); // min 5, max 10, value to wrap 12: returns 7

    The example above returns 7 because 12 is 2 more than the maximum of 10, so it wraps around to the start and moves 2 steps forward from there. In a carousel, this can be used to loop infinitely through the slides.

    Here’s a simple demo of how it can be applied:

    In the HTML, a <nav> block has been added that contains previous/next buttons and progress text:

    <nav class="carousel-nav">
      <button class="prev" tabindex="0" aria-label="Previous Slide"></button>
      <button class="next" tabindex="0" aria-label="Next Slide"></button>
      <div>1/8</div>
    </nav>

    A few new rules have been added to the CSS, most importantly to .carousel-slide-abs:

    .carousel-slide-abs {
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      width: 75vw;
      height: 70vh;
    }

    In the JS, we override the carousel’s scroll-snap-type and display the <nav> block. Since we no longer have a scrollable area, the buttons are necessary to maintain keyboard accessibility. Safari requires tabindex="0" to allow users to tab to them. Additionally, aria-labels are important since the buttons have no visible text content.

    We apply the new class to each slide, which effectively stacks them all in the center. We also set the initial opacity: 1 for the first slide and 0 for the rest:

    gsap.set(".carousel", { "scroll-snap-type": "none" });
    
    gsap.set(".carousel-nav", { display: "block" });
    
    slides.forEach((slide, i) => {
      slide.classList.add("carousel-slide-abs");
      gsap.set(slide, { opacity: (i === 0 ? 1 : 0) });
    });

    Next, we need a function that transitions to the previous or next slide. changeSlide() is passed a direction parameter of either positive or negative 1. Inside this function, we:

    1. Fade out the current slide
    2. Update the current slide index using gsap.utils.wrap()
    3. Fade in the new current slide
    4. Update the progress text

    The different easing on the outro and intro tweens helps prevent excessive overlapping opacity during the crossfade.

    next.addEventListener("click", () => changeSlide( 1 ));
    prev.addEventListener("click", () => changeSlide( -1 ));
    
    function changeSlide( dir ) {
      
      gsap.to(slides[currentIndex], { opacity: 0, ease: "power3" });
      
      currentIndex = gsap.utils.wrap(0, slides.length, (currentIndex += dir));
      
      gsap.to(slides[currentIndex], { opacity: 1, ease: "power3.inOut" });
      
      gsap.set(".carousel-nav div", { innerText: `${currentIndex + 1}/${slides.length}` });
    
    }

    Polishing the Transition – GSAP Demo 1B

    To take this idea further, let’s add more detail to the outro and intro animations:

    For the 3D perspective to work, we’ve added perspective: 750px to .carousel-slide-abs in the CSS.

    Instead of targeting the slides themselves, we set the opacity of their child elements to 0—except for those in the first slide.

     gsap.set(slide.children, { opacity: (i === 0 ? 1 : 0) });

    Then, we do the following inside changeSlide():

    1. Store a reference to the outgoing slide’s children
    2. Update currentIndex, just as before
    3. Create a const for the incoming slide’s children
    4. Kill tweens on both slides’ children to prevent conflicts if slides change rapidly
    5. Create a timeline for the transition:
    gsap.timeline({ defaults:{ ease: "expo" } })
      // update progress text
      .set(".carousel-nav div", { innerText: `${currentIndex + 1}/${slides.length}` })
    
      // old slide outro
      .to(oldLayers[0], {
        duration: 0.3,
        rotateY: (dir<0 ? -75 : 75),
        scale: 0.6,
        ease: "power2.in"
      }, 0)
      .to(oldLayers, {
        duration: 0.3,
        opacity: 0,
        ease: "power2.in"
      }, 0)
    
      // new slide intro
      .to(newLayers, {
        opacity: 1,
        ease: "power1.inOut",
        stagger: 0.2
      }, 0.2)
      .fromTo(newLayers[0], {
        rotateY: (dir<0 ? 90 : -90),
        scale: 0.6
      },{
        rotateY: 0,
        scale: 1
      }, 0.3)
      .fromTo([newLayers[1], newLayers[2]], {
        y: 35
      },{
        duration: 1,
        y: 0,
        stagger: 0.14
      }, 0.4);

    Easing and staggers help smooth out and space the movement. The dir parameter modifies the rotationY, adding a subtly unique motion to previous and next actions.

    This basic setup can be easily customized further. Animating a clip-path, applying a blur filter, or experimenting with additional 3D transforms could all produce interesting results.

    A Different Approach – GSAP Demo 2A

    Another way to create a seamless looping carousel with GSAP is to use the horizontalLoop() helper function. Although GSAP helper functions aren’t officially part of the core library, they’re a handy collection of code snippets and shortcuts. They also serve as great learning resources for writing more advanced GSAP code.

    This specific helper function animates elements along their x-axis and repositions them once they’re out of view to create an infinite loop. Here’s a basic implementation:

    Again, we override the CSS and display the <nav> element. Then we call horizontalLoop(), which takes two parameters: an array of the carousel slides and a config object for setting various options.

    const loop = horizontalLoop(slides, {
      paused: true,       // no auto-scroll
      paddingRight: 10,   // match the 10px flex gap
      center: true,       // snap the active slide to the center
      onChange: (slide, index) => { // called when the active slide changes
        if (activeSlide) {
          gsap.to(".active", { opacity: 0.3 });
          activeSlide.classList.remove("active");
        }
        slide.classList.add("active");
        activeSlide = slide;
        gsap.to(".active", { opacity: 1, ease: "power2.inOut" });
        gsap.set(".carousel-nav div", { innerText: `${index + 1}/${slides.length}` });
      }
    });

    The most notable of these options is the onChange callback, where we can write code that executes each time the active slide changes. In this example, we’re removing and adding the “active” class name and tweening the opacity to draw more focus to the center slide.

    The helper function returns a timeline with several useful added methods, including next(), previous(), and toIndex(). We’ll use these to add navigation functionality to our previous/next buttons, as well as to the individual slides:

    next.addEventListener("click", () => loop.next({ duration: 1, ease: "expo" }));
    prev.addEventListener("click", () => loop.previous({ duration: 1, ease: "expo" }));
    
    // each slide can function as a button to activate itself
    slides.forEach((slide, i) => {
      slide.addEventListener("click", () => loop.toIndex(i, {duration: 1, ease: "expo"}))
    });

    Finally, we set the initial carousel state by adjusting the opacity of each slide and calling toIndex() with no tween duration, which centers the active slide.

    gsap.set(".carousel-slide", { opacity: (i) => (i === 0 ? 1 : 0.3) });
    
    loop.toIndex(0, { duration: 0 }); 

    If you’re unfamiliar with function-based values in GSAP, this is an amazing feature—definitely check out that link to learn how they work. Here, we’re iterating through each element with the class name “carousel-slide,” returning an opacity value of 1 for the first slide and 0.3 for the rest.

    The remainder of the JS is just the helper function, copied and pasted from the GSAP docs demo. In most cases, you won’t need to modify anything inside it. (We’ll look at an exception in Demo 2C.)

    Add Draggable & InertiaPlugin – GSAP Demo 2B

    To make the carousel move on drag, we’ll need two plugins: Draggable and the Inertia Plugin. Once those scripts are included, you can set draggable: true in the config object.

    In addition to drag behavior, this iteration includes some text animation, with logic to prevent it from running on the first load (plus hover in/out animations on the nav buttons).

    onChange: (slide, index) => { // called when the active slide changes
      if (activeSlide) {
        gsap.to(".carousel h2, .carousel h5", { overwrite: true, opacity: 0, ease: "power3" });
        gsap.to(".active", { opacity: 0.3 });
        activeSlide.classList.remove("active");
      }
      slide.classList.add("active");
      activeSlide = slide;
      
      // intro animation for new active slide
      gsap.timeline({ defaults:{ ease:"power1.inOut" } })
    
        // fade in the new active slide
        .to(".active", { opacity: 1, ease: "power2.inOut" }, 0)
    
        // fade out the progress text, change its value, fade it back in
        .to(".carousel-nav div", { duration: 0.2, opacity: 0, ease: "power1.in" }, 0)
        .set(".carousel-nav div", { innerText: `${index + 1}/${slides.length}` }, 0.2)
        .to(".carousel-nav div", { duration: 0.4, opacity: 0.5, ease: "power1.inOut" }, 0.2)
    
        // fade in the text elements and translate them vertically
        .to(".active h2, .active h5", { opacity: 1, ease: "power1.inOut" }, 0.3)
        .fromTo(".active h2, .active h5", { y:(i)=>[40,60][i] },{ duration: 1.5, y: 0, ease: "expo" }, 0.3)
    
        // skip active slide animation on first run
        .progress( firstRun? 1: 0 )
    }

    Adding Parallax – GSAP Demo 2C

    To make the movement more engaging, let’s calculate each slide’s horizontal progress and use it to create a parallax effect.

    Until now, we haven’t modified the helper function. However, to calculate slide progress, this version includes one change inside horizontalLoop().

    Now, every time the carousel timeline updates, slideImgUpdate() is called. This function sets each image’s xPercent based on the progress of its parent slide. Progress is 0 when the slide is offstage to the left, and 1 when it’s offstage to the right.

    function slideImgUpdate(){
      slides.forEach( slide => {
        const rect = slide.getBoundingClientRect();
        const prog = gsap.utils.mapRange(-rect.width, innerWidth, 0, 1, rect.x);
        const val = gsap.utils.clamp(0, 1, prog );
        gsap.set(slide.querySelector("img"), {
          xPercent: gsap.utils.interpolate(0, -50, val)
        });
      });
    }

    GSAP utility functions mapRange(), interpolate(), and clamp() make the progress calculation much easier. Note, in the CSS, the width of .carousel-slide img is increased to 150%, so there will be enough image for a 50% horizontal movement.

    Taking It Further

    There are endless ways you could build on these demos, customizing both appearance and functionality. A few ideas include:

    • Modify how many slides are shown at once—a single, full-frame version could be interesting, as could several smaller slides to create a cover flow effect. In both of those examples, the progress indicator also became a fun area for experimentation.
    • Additional details could be added by calling custom functions inside the helper function’s onPress, onRelease, or onThrowComplete callbacks. Here’s one more iteration on Demo 2, where the entire carousel shrinks while the pointer is held down.
    • The carousel could even serve as navigation for a separate animated page element, like on Nite Riot.
    • If you want the carousel to respond to mouse wheel movements, GSAP’s Observer plugin offers an easy way to handle those events.
    • With GSAP’s matchMedia(), you can specify different animations for various viewport widths and tailor behavior for users who prefer reduced motion.



    Source link

  • Upgrading a 20 year old University Project to .NET 6 with dotnet-upgrade-assistant

    Upgrading a 20 year old University Project to .NET 6 with dotnet-upgrade-assistant



    I wrote a Tiny Virtual Operating System for a 300-level OS class in C# for college back in 2001 (?) and later moved it to VB.NET in 2002. This is all pre-.NET Core, and on early .NET 1.1 or 2.0 on Windows. I moved it to GitHub 5 years ago and ported it to .NET Core 2.0 at the time. At this point it was 15 years old, so it was cool to see this project running on Windows, Linux, in Docker, and on a Raspberry Pi…a machine that didn’t exist when the project was originally written.

    NOTE: If the timeline is confusing, I had already been working in industry for years at this point but was still plugging away at my 4 year degree at night. It eventually took 11 years to complete my BS in Software Engineering.

    This evening, as the children slept, I wanted to see if I could run the .NET Upgrade Assistant on this now 20 year old app and get it running on .NET 6.

    Let’s start:

    $ upgrade-assistant upgrade .\TinyOS.sln
    -----------------------------------------------------------------------------------------------------------------
    Microsoft .NET Upgrade Assistant v0.3.256001+3c4e05c787f588e940fe73bfa78d7eedfe0190bd

    We are interested in your feedback! Please use the following link to open a survey: https://aka.ms/DotNetUASurvey
    -----------------------------------------------------------------------------------------------------------------

    [22:58:01 INF] Loaded 5 extensions
    [22:58:02 INF] Using MSBuild from C:\Program Files\dotnet\sdk\6.0.100\
    [22:58:02 INF] Using Visual Studio install from C:\Program Files\Microsoft Visual Studio\2022\Preview [v17]
    [22:58:06 INF] Initializing upgrade step Select an entrypoint
    [22:58:07 INF] Setting entrypoint to only project in solution: C:\Users\scott\TinyOS\src\TinyOSCore\TinyOSCore.csproj
    [22:58:07 INF] Recommending executable TFM net6.0 because the project builds to an executable
    [22:58:07 INF] Initializing upgrade step Select project to upgrade
    [22:58:07 INF] Recommending executable TFM net6.0 because the project builds to an executable
    [22:58:07 INF] Recommending executable TFM net6.0 because the project builds to an executable
    [22:58:07 INF] Initializing upgrade step Back up project

    See how the process is interactive at the command line, with color prompts and a series of dynamic multiple-choice questions?

    Updating .NET project with the upgrade assistant

    Interestingly, it builds on the first try, no errors.

    When I manually look at the .csproj I can see some weird version numbers, likely from some not-quite-baked version of .NET Core 2 I used many years ago. My spidey sense says this is wrong, and I’m assuming the upgrade assistant didn’t understand it.

        <!-- <PackageReference Include="ILLink.Tasks" Version="0.1.4-preview-906439" /> -->
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.0-preview2-final" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0-preview2-final" />
    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.0.0-preview2-final" />
    <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0-preview2-final" />

    I also note a commented-out reference to ILLink.Tasks which was a preview feature in Mono’s Linker to reduce the final size of apps and tree-trim them. Some of that functionality is built into .NET 6 now so I’ll use that during the build and packaging process later. The reference is not needed today.

    I’m gonna blindly upgrade them to .NET 6 and see what happens. I could do this by just changing the numbers and seeing if it restores and builds, but I can also try dotnet outdated which remains a lovely tool in the upgrader’s toolkit.

    image

    This “outdated” tool is nice as it talks to NuGet and confirms that there are newer versions of certain packages.

    In my tests – which were just batch files at this early time – I was calling my dotnet app like this:

    dotnet netcoreapp2.0/TinyOSCore.dll 512 scott13.txt  

    This will change to the modern form with just TinyOSCore.exe 512 scott13.txt with an exe and args and no ceremony.

    Publishing and trimming my TinyOS turns into just a 15 meg EXE. Nice considering that the .NET I need is in there with no separate install. I could turn this little synthetic OS into a microservice if I wanted to be totally extra.

    dotnet publish -r win-x64 --self-contained -p:PublishSingleFile=true -p:SuppressTrimAnalysisWarnings=true

    If I add

    -p:EnableCompressionInSingleFile=true

    Then it’s even smaller. No code changes. Run all my tests, looks good. My project from university from .NET 1.1 is now .NET 6.0, cross platform, self-contained in 11 megs in a single EXE. Sweet.


    Sponsor: At Rocket Mortgage® the work you do around here will be 100% impactful but won’t take all your free time, giving you the perfect work-life balance. Or as we call it, tech/life balance! Learn more.




    About Scott

    Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

    facebook
    bluesky
    subscribe
    About   Newsletter

    Hosting By
    Hosted on Linux using .NET in an Azure App Service










    Source link

  • Build a Python Site Connectivity Checker App with PyQt (Step-by-Step)



    Build a Python Site Connectivity Checker App with PyQt (Step-by-Step)



    Source link

  • Build a Python Network Speed Test App with PyQt (Step-by-Step)



    Build a Python Network Speed Test App with PyQt (Step-by-Step)



    Source link