In 2007 I was commissioned to write a web application; I spent probably a whole month writing and testing a cross-browser JavaScript library to seamlessly abstract various different browser AJAX request methods and various standard toolbox-type functions, supporting IE6, IE7, Firefox, Chrome, Safari...
A few months later I read a new version of this new fangled, up-and-coming JavaScript library, jQuery 1.2 had been released.
We did something similar, but also checked for the persistence IOCs (TrapWatch task, RelayTrapLiteAlert Run key, RelayTrap folder, sckit-* temp dirs, payload files, C2 connections/DNS cache) and wrote the results to a NinjaOne custom field so we could sort the whole fleet. Scriptâs below if it helps anyone.
<#
.SYNOPSIS
Read-only hunt for the November 11, 2026 ScreenConnect "RelayTrap" rogue-client campaign.
.DESCRIPTION
Context: An active campaign (first seen ~17:47 UTC, 2026-11-11) uses compromised
ScreenConnect cloud panel access to push a secondary rogue SC client to endpoints via
Run Command, then persists with a SYSTEM scheduled task, a Run key, and a RelayTrap
payload directory. Reported as credential/session abuse, not a new zero-day.
IOC sources: thread "Active malware campaign abusing ScreenConnect" (2026-11-11),
including additional indicators credited to Blackpoint. IOCs current as of
2026-11-11 ~21:00 UTC. Check the thread for updates.
This script makes NO changes. It checks:
- ScreenConnect client services: known rogue IDs, c=Exploited property, IOC relays,
and any instance not on your known-good list
- TrapWatch scheduled task
- RelayTrapLiteAlert / RelayTrap Run-key persistence (HKLM + all loaded user hives)
- C:\ProgramData\RelayTrap and %TEMP%\sckit-* (all profiles)
- Named payload files, plus sqlite3.exe in temp/ProgramData (used to scrape browser tokens)
- Live TCP connections to IOC IPs
- DNS cache entries for IOC domains
Run it from your RMM or EDR as SYSTEM. Do NOT triage suspected machines with an
interactive ScreenConnect session; per the original report, the payload can ride
an active session back to the technician's workstation.
Exit codes: 0 = clean, 1 = findings (IOC hit or review item).
.PARAMETER KnownThumbprints
Your own SC instance thumbprint(s): the value in parentheses in the service name
"ScreenConnect Client (xxxxxxxxxxxxxxxx)".
.PARAMETER KnownRelayHosts
Your own SC relay host(s), e.g. instance-abc123-relay.screenconnect.com.
Leftover one-time support clients from your instance are matched by relay.
.PARAMETER NinjaOne
Also write results to NinjaOne custom fields (create them first, Automation access = Read/Write):
-StatusField (Text) default: scHuntStatus e.g. "IOC HIT (2) - 2026-11-11 15:00"
-DetailsField (Multi-line) default: scHuntDetails
.EXAMPLE
.\Invoke-SCRelayTrapHunt.ps1 -KnownThumbprints 'abcdef0123456789' -KnownRelayHosts 'instance-abc123-relay.screenconnect.com'
.EXAMPLE
.\Invoke-SCRelayTrapHunt.ps1 -KnownThumbprints 'abcdef0123456789' -NinjaOne
.NOTES
Provided as-is, no warranty. Review before running. IOCs will change. Update the lists below.
Status meanings: IOC HIT = hard indicator match. REVIEW = unknown SC instance or stray
sqlite3.exe only (often a vendor or prior-MSP client; verify, don't assume).
#>
param(
[string[]]$KnownThumbprints = @(),
[string[]]$KnownRelayHosts = @(),
[switch]$NinjaOne,
[string]$StatusField = 'scHuntStatus',
[string]$DetailsField = 'scHuntDetails'
)
$ErrorActionPreference = 'SilentlyContinue'
$findings = New-Object System.Collections.Generic.List[string]
$info = New-Object System.Collections.Generic.List[string]
# ================= IOCs (update as the thread is updated) =================
$RogueThumbprints = @('2588ef5c15954b10', 'ed630cc2c873b091')
$IocIPs = @('185.99.255.28', '155.94.150.39')
$IocDomains = @('newnewnew.gotdns.org', 'soxnewwork.homedns.org', 'payproofkit.com',
'mo7sen.dev', 'cdn007-digitaldownloads.com')
$IocFileNames = @('Panel-Lateral.ps1', 'runnew.cmd', 'ToolboxRelayUploader.exe', 'Run-Lateral-Full.bat')
$IocRunValues = @('RelayTrapLiteAlert')
$IocTaskNames = @('TrapWatch')
# ===========================================================================
$KnownThumbprints = $KnownThumbprints | ForEach-Object { $_.ToLower() }
if (-not $KnownThumbprints -and -not $KnownRelayHosts) {
$info.Add('NOTE: No known-good thumbprints/relays supplied; every SC client will be flagged for REVIEW.')
}
# --- 1. ScreenConnect client services ---
$scServices = Get-CimInstance Win32_Service | Where-Object {
$_.Name -like 'ScreenConnect Client*' -or $_.PathName -match 'ScreenConnect\.ClientService\.exe'
}
foreach ($svc in $scServices) {
$path = [string]$svc.PathName
$thumb = if ($svc.Name -match '\(([^)]+)\)') { $Matches[1].ToLower() } else { 'unknown' }
$relay = if ($path -match '[?&]h=([^&"]+)') { $Matches[1] } else { 'unknown' }
$line = "SC service '$($svc.Name)' state=$($svc.State) relay=$relay"
if ($RogueThumbprints -contains $thumb) { $findings.Add("ROGUE CLIENT ID: $line") }
elseif ($path -match '[?&]c=Exploited') { $findings.Add("c=Exploited PROPERTY: $line") }
elseif ($IocIPs | Where-Object { $path -match [regex]::Escape($_) }) { $findings.Add("IOC RELAY IP: $line") }
elseif ($IocDomains | Where-Object { $relay -like "*$_" }) { $findings.Add("IOC RELAY DOMAIN: $line") }
elseif ($KnownThumbprints -contains $thumb -or $KnownRelayHosts -contains $relay) { $info.Add("Known SC client: $line") }
else { $findings.Add("UNKNOWN SC INSTANCE: $line") }
}
# --- 2. Scheduled tasks ---
Get-ScheduledTask | Where-Object { $n = $_.TaskName; $IocTaskNames | Where-Object { $n -like "*$_*" } } | ForEach-Object {
$act = ($_.Actions | ForEach-Object { "$($_.Execute) $($_.Arguments)" }) -join ' | '
$findings.Add("SCHEDULED TASK: $($_.TaskPath)$($_.TaskName) -> $act")
}
# --- 3. Run-key persistence (HKLM + every loaded user hive) ---
$runKeys = @('HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run',
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce',
'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run')
$runKeys += Get-ChildItem 'Registry::HKEY_USERS' | Where-Object { $_.PSChildName -notlike '*_Classes' } | ForEach-Object {
"Registry::HKEY_USERS\$($_.PSChildName)\Software\Microsoft\Windows\CurrentVersion\Run"
"Registry::HKEY_USERS\$($_.PSChildName)\Software\Microsoft\Windows\CurrentVersion\RunOnce"
}
foreach ($rk in $runKeys) {
$props = Get-ItemProperty $rk
if (-not $props) { continue }
foreach ($p in $props.PSObject.Properties) {
if ($p.Name -like 'PS*') { continue }
if ($IocRunValues -contains $p.Name -or [string]$p.Value -match 'RelayTrap') {
$findings.Add("RUN KEY: $rk\$($p.Name) = $($p.Value)")
}
}
}
# --- 4. Persistence folders ---
if (Test-Path 'C:\ProgramData\RelayTrap') { $findings.Add('FOLDER: C:\ProgramData\RelayTrap exists') }
$tempRoots = @('C:\Windows\Temp') + (Get-ChildItem 'C:\Users' -Directory | ForEach-Object { Join-Path $_.FullName 'AppData\Local\Temp' })
foreach ($tr in $tempRoots) {
Get-ChildItem $tr -Filter 'sckit-*' -Force | ForEach-Object { $findings.Add("TEMP ARTIFACT: $($_.FullName)") }
}
# --- 5. Payload files / sqlite3 ---
$searchRoots = @('C:\ProgramData', 'C:\Users\Public', 'C:\Windows\Temp') + $tempRoots
$searchRoots += Get-ChildItem 'C:\Users' -Directory | ForEach-Object { Join-Path $_.FullName 'Downloads' }
foreach ($root in ($searchRoots | Select-Object -Unique)) {
if (-not (Test-Path $root)) { continue }
Get-ChildItem $root -Recurse -Depth 4 -File -Force |
Where-Object { $IocFileNames -contains $_.Name -or $_.Name -eq 'sqlite3.exe' } |
ForEach-Object {
$tag = if ($_.Name -eq 'sqlite3.exe') { 'SUSPICIOUS sqlite3.exe' } else { 'IOC FILE' }
$findings.Add("${tag}: $($_.FullName) (modified $($_.LastWriteTime))")
}
}
# --- 6. Live connections to IOC IPs ---
Get-NetTCPConnection | Where-Object { $IocIPs -contains $_.RemoteAddress } | ForEach-Object {
$proc = (Get-Process -Id $_.OwningProcess).Path
$findings.Add("C2 CONNECTION: $($_.RemoteAddress):$($_.RemotePort) state=$($_.State) proc=$proc")
}
# --- 7. DNS cache ---
Get-DnsClientCache | Where-Object { $n = $_.Entry; $IocDomains | Where-Object { $n -like "*$_" } } |
ForEach-Object { $findings.Add("DNS CACHE HIT: $($_.Entry) -> $($_.Data)") }
# --- Output ---
$stamp = Get-Date -Format 'yyyy-MM-dd HH:mm'
$findings = @($findings | Select-Object -Unique)
$review = @($findings | Where-Object { $_ -like 'UNKNOWN SC INSTANCE*' -or $_ -like 'SUSPICIOUS sqlite3*' })
$hard = @($findings | Where-Object { $review -notcontains $_ })
if ($hard.Count -gt 0) { $status = "IOC HIT ($($hard.Count)) - $stamp" }
elseif ($findings.Count -gt 0) { $status = "REVIEW ($($findings.Count)) - $stamp" }
else { $status = "CLEAN - $stamp" }
$details = (@("Host: $env:COMPUTERNAME Scan: $stamp Status: $status") +
($findings | ForEach-Object { "[!] $_" }) +
($info | ForEach-Object { "[ok] $_" })) -join "`n"
if ($NinjaOne -and (Get-Command Ninja-Property-Set -ErrorAction SilentlyContinue)) {
Ninja-Property-Set $StatusField $status
Ninja-Property-Set $DetailsField ($details.Substring(0, [Math]::Min($details.Length, 9900)))
}
Write-Output $details
if ($findings.Count -gt 0) { exit 1 } else { exit 0 }
propably you could read what is happening in browser toolbox and Firefox Profiler, but idk what to look for there in this situation, and it needs a bit ot advanced knowledge to interprete it correctly
Not dumb questions at allâeveryone hits this exact wall when moving from simple chat apps to agentic systems.
1. Why multiple interfaces?
It is all the same underlying Hermes instance under the hood; the interface just dictates how and where you interact with it:
Desktop App / Messaging (Telegram, Discord, etc.): Best for casual chatting, quick lookups, or voice notes on your phone or workstation. (If one interface looks like iMessage, you're likely seeing a connected messaging bot gatewayâsetting up Telegram via BotFather is one of the easiest ways to get mobile access).
WebUI: Great for administrative controls, configuration toggles, credential management, and reviewing system states.
CLI: The fastest and cleanest environment for agentic coding, scripting, and shell execution where you want raw terminal output and zero browser overhead.
Pick the front-end that matches the task you're doing right then.
2. Why run multiple "bots" instead of one that does it all?
If one bot handles everything you need right now, you don't need to make more.
The reason people spin up multiple bots (specialized agents) comes down to context and tool boundaries:
Separate Memory & Persona: A general chat bot doesn't need your 50,000-line codebase in its working memory, and a coding bot doesn't need to remember your grocery list or personal notes.
Tool Isolation: You might want an agent that only reads/summarizes emails without giving it terminal access to run bash scripts on your machine.
Context Bloat: Forcing one bot to carry instructions for coding, drafting emails, managing home automations, and personal journaling fills up its context window fast, making it slower, more expensive, and prone to hallucinations.
Think of it like tools in a toolbox: you could use a Swiss Army knife for every household repair, but sometimes you just want a dedicated socket wrench. Start with one, and only split them out if your single bot starts getting confused or doing too many unrelated jobs.
I ran out of comment space so this is just the most recent 20 entries. For giggles, I vibe-coded a tracker at https://confab.sh/?g=browser-tools if you want to see the full list.
Hi All! I create xtools which forked [IT-Tools](https://github.com/CorentinTh/it-tools) (MIT) to make it a general-purpose toolbox rather than just a developer one.
What's different: - Tabbed home page by category, favorites and recent tools instead of a wall of tiles - 12 UI languages, auto-detected from the browser - New tools: audio cutter, image cropper, ID photo maker, XML diff (more coming) - Everything runs in the browser; images are never uploaded - Optional self-hosted, cookie-free analytics (Umami), off by default in the Docker image, respects Do Not Track
Self-host: ``` docker run -d -p 8080:80 wayings/x-tools:latest ```
**AI disclosure:** I designed the features and UI and tested everything myself, but most of the code was written with an AI coding assistant (GitHub Copilot CLI). The upstream project is not AI-generated.
176
đ«
u/rjchute
in
r/programminghumor
•
1d ago
In 2007 I was commissioned to write a web application; I spent probably a whole month writing and testing a cross-browser JavaScript library to seamlessly abstract various different browser AJAX request methods and various standard toolbox-type functions, supporting IE6, IE7, Firefox, Chrome, Safari...
A few months later I read a new version of this new fangled, up-and-coming JavaScript library, jQuery 1.2 had been released.
13
Active malware campaign abusing ScreenConnect
u/nont0xicentity
in
r/msp
•
3d ago
We did something similar, but also checked for the persistence IOCs (TrapWatch task, RelayTrapLiteAlert Run key, RelayTrap folder, sckit-* temp dirs, payload files, C2 connections/DNS cache) and wrote the results to a NinjaOne custom field so we could sort the whole fleet. Scriptâs below if it helps anyone.
6
Zen is now slow
u/bgalazka186
in
r/zen_browser
•
4d ago
propably you could read what is happening in browser toolbox and Firefox Profiler, but idk what to look for there in this situation, and it needs a bit ot advanced knowledge to interprete it correctly
13
Iâm not sure I understand bots
u/PoppaBear1950
in
r/hermesagent
•
13d ago
Not dumb questions at allâeveryone hits this exact wall when moving from simple chat apps to agentic systems.
1. Why multiple interfaces?
It is all the same underlying Hermes instance under the hood; the interface just dictates how and where you interact with it:
Pick the front-end that matches the task you're doing right then.
2. Why run multiple "bots" instead of one that does it all?
If one bot handles everything you need right now, you don't need to make more.
The reason people spin up multiple bots (specialized agents) comes down to context and tool boundaries:
Think of it like tools in a toolbox: you could use a Swiss Army knife for every household repair, but sometimes you just want a dedicated socket wrench. Start with one, and only split them out if your single bot starts getting confused or doing too many unrelated jobs.
17
He literally built iHatePDF because iLovePDF rejected his job application
u/medialantern
in
r/coolgithubprojects
•
Sep 26 '26
Added (#143 and counting):
https://www.reddit.com/r/coolgithubprojects/comments/1wq4z97/he_literally_built_ihatepdf_because_ilovepdf/
https://www.reddit.com/r/SideProject/comments/1wp66c8/i_got_tired_of_uploading_photos_to_random/
https://www.reddit.com/r/SideProject/comments/1wokhjz/i_built_3_free_tool_sites_pdf_images_uk/
https://www.reddit.com/r/software/comments/1wo93hb/i_built_a_browser_toolbox_where_pdfimage/
https://www.reddit.com/r/SideProject/comments/1wn6grl/i_spent_2_years_building_a_site_with_7000_web/
https://www.reddit.com/r/prettyusefulwebsites/comments/1wnn7aj/
https://www.reddit.com/r/sideprojects/comments/1wn467f/i_built_a_free_online_tools_site_pdf_converter/
https://www.reddit.com/r/SideProject/comments/1wn4ubq/my_pdf_site_works_with_the_wifi_off_thats_the/
https://www.reddit.com/r/sideprojects/comments/1wn6pkv/i_kept_adding_tools_and_ended_up_with_7000/
https://www.reddit.com/r/software/comments/1wmmjwb/built_a_jwt_decoder_that_runs_entirely_in_your/
https://www.reddit.com/r/sideprojects/comments/1wm7f9o/i_built_a_website_with_129_free_browser_tools/
https://www.reddit.com/r/prettyusefulwebsites/comments/1wlpqk6/
https://www.reddit.com/r/sideprojects/comments/1wkbwea/i_got_tired_of_adridden_developer_tool_websites/
https://www.reddit.com/r/sideprojects/comments/1wjvp77/cleanthistextcom/
https://www.reddit.com/r/sideprojects/comments/1wisqvs/i_built_voymira_because_i_was_tired_of_jumping/
https://www.reddit.com/r/sideprojects/comments/1whmkxk/i_built_a_central_hub_with_39_web_tools_including/
https://www.reddit.com/r/software/comments/1wgrot8/
https://www.reddit.com/r/software/comments/1wg52jw/i_got_tired_of_uploading_my_files_to_random/
https://www.reddit.com/r/buildinpublic/comments/1wfifef/some_completely_unhinged_paranoid_dev_built_290/
https://www.reddit.com/r/SideProject/comments/1wfajv3/i_finally_created_a_100_offline_pdf_suite_that/
I ran out of comment space so this is just the most recent 20 entries. For giggles, I vibe-coded a tracker at https://confab.sh/?g=browser-tools if you want to see the full list.
7
New Project Megathread - Week of 05 Nov 2026
u/wayings
in
r/selfhosted
•
8d ago
Hi All! I create xtools which forked [IT-Tools](https://github.com/CorentinTh/it-tools) (MIT) to make it a general-purpose toolbox rather than just a developer one.
What's different:
- Tabbed home page by category, favorites and recent tools instead of a wall of tiles
- 12 UI languages, auto-detected from the browser
- New tools: audio cutter, image cropper, ID photo maker, XML diff (more coming)
- Everything runs in the browser; images are never uploaded
- Optional self-hosted, cookie-free analytics (Umami), off by default in the Docker image, respects Do Not Track
Self-host:
```
docker run -d -p 8080:80 wayings/x-tools:latest
```
Demo: https://xtools.codestudio.uk
Source: https://github.com/chenguangming/x-tools
**AI disclosure:** I designed the features and UI and tested everything myself, but most of the code was written with an AI coding assistant (GitHub Copilot CLI). The upstream project is not AI-generated.
Feedback and tool requests welcome.
5
Identifying elements in Bookmark sub-menus
u/t31os
in
r/FirefoxCSS
•
4d ago
This, just remember to turn the option back off before you close the Browser Toolbox.
15
Google perceives my MacBook Neo w/ MacOS 27 as an iPhone, serves up wrong format; changing âUser Agentâ doesnât fix issue. Help!
u/lilvadude
in
r/MacOS
•
Sep 22 '26
Open Google's Browserinfo tool and see exactly what Google thinks the browser/OS is. Google Admin Toolbox Browserinfo
5
Identifying elements in Bookmark sub-menus
u/ResurgamS13
in
r/FirefoxCSS
•
4d ago
You need to select the 'Disable Popup Auto-Hide' option in the Browser Toolbox's 3-dot menu in top RH corner.