Skip to content

Embedded browser with tunnel proxy, bookmarks & AxScript API#306

Open
shashinma wants to merge 11 commits intoAdaptix-Framework:dev-v1.3from
shashinma:dev-v1.3-browser
Open

Embedded browser with tunnel proxy, bookmarks & AxScript API#306
shashinma wants to merge 11 commits intoAdaptix-Framework:dev-v1.3from
shashinma:dev-v1.3-browser

Conversation

@shashinma
Copy link
Copy Markdown
Contributor

Summary

  • Embedded browser based on Qt WebEngine with two modes: Full (tabs, navigation, bookmarks, proxy popover, DevTools) and Chromeless (single page without UI chrome, isolated profile per panel).
  • AxScript API for controlling the browser from scripts and extender payloads: opening panels, declarative sync of chromeless modules via JSON.
  • Go toolchain upgrade to 1.26.1 in Dockerfile and install script.

Changes

Embedded Browser — Full mode

  • EmbeddableBrowserWidget: multi-tab QWebEngineView, shared profile, bookmark home grid, navigation bar, proxy popover (SOCKS5/HTTP/manual), tunnel list, DevTools, detach to separate window, adaptix-browser:// internal URLs.
  • Integrated into the main toolbar (globe button) with LoadBrowserUI(url, proxyHost, proxyPort).
  • Qt WebEngine is optional (HAS_QT_WEBENGINE); the client builds without it.

Features preview

Homepage with bookmark tiles, tabs & proxy popover
The home page displays a tile grid of bookmarked sites with favicons. Tabs run along the top; the bookmarks bar auto-trims to fit available width. The proxy popover lets the operator pick an active SOCKS5 tunnel or enter a custom host:port.

Homepage with bookmark tiles, tabs and proxy popover

Proxy popover — tunnel picker & manual mode
Left: tunnel picker dropdown listing active SOCKS5 tunnels by agent name. Right: after selecting a tunnel, the proxy type, host and port are auto-filled (bind address normalized to 127.0.0.1).

Proxy popover — tunnel picker Proxy popover — manual mode with auto-filled host:port

Browsing an internal target through a SOCKS5 tunnel
Navigating to an internal OWA (Outlook Web Access) page at 10.154.21.34 via a SOCKS5 tunnel bound to agent LMILLER. All browser traffic is routed through the beacon's tunnel — no external tools or browser configuration required.

Browsing OWA through SOCKS5 tunnel

Back button long-press history menu
Long-pressing the Back button opens a dropdown with the last 25 visited pages, allowing quick jumps without clicking Back repeatedly.

Back button long-press history menu

Detached browser in a separate window
The browser can be detached into a standalone floating window. Multi-tab browsing, navigation, bookmarks and proxy settings remain fully functional. Closing the window re-parents the browser back into the dock.

Detached browser in a separate window

Embedded Browser — Chromeless mode

  • BrowserChromeMode enum with fullMode / chromelessMode factories.
  • Chromeless: dedicated QWebEngineProfile per logicalId, single QWebEngineView, no tabs, toolbar, bookmarks, or DevTools.
  • AdaptixWidget manages chromeless panels (chromelessWebPanels map) — create/reuse/remove ext docks.
  • applyChromelessWebModulesJson — declarative panel sync from JSON: creates new panels, updates existing ones, closes removed ones.

AxScript API

  • open_embedded_browser — opens Full browser with optional URL and SOCKS proxy.
  • open_web_panel(chromeless, panelId, title, url, ...) — opens a Full or Chromeless panel.
  • apply_chromeless_web_modules(jsonPayload) — batch sync of chromeless panels.
  • All entry points compile as no-ops without HAS_QT_WEBENGINE.

UI / qlementine

  • Popover::relayoutToContent() — recomputes popover geometry when inner content changes size.
  • PNG icons for toolbar and home page (globe, home, tab bar, DevTools, bookmarks, star, edit, delete, detach).
  • Proper setUpdatesEnabled on browser docks during sync pause.

Infrastructure

  • Go toolchain 1.25 → 1.26.1 in Dockerfile, pre_install_linux_all.sh, gopher_agent/src_gopher/go.mod.

Lists the Qt WebEngine development package next to other Qt6 modules in
pre_install_linux_all.sh so Linux setups can install optional WebEngine
headers/libs needed to build AdaptixClient with the embedded browser.
Exposes a small API to recompute popover frame geometry and mask after
inner widgets change size or visibility. Used when proxy popover content
toggles rows (e.g. host/port) so fixed-size content does not leave a
blank gap.
Add PNG assets for toolbar and home page: globe, home, tab bar toggles,
DevTools open/close, bookmark bar, star (filled/outline), edit/delete,
and detach-to-window. Wire aliases in Resources.qrc for :/icons/… URLs.
Build: find Qt6 WebEngineWidgets with QUIET, set HAS_WEBENGINE; when
found, add EmbeddableBrowserWidget sources, link Qt6::WebEngineWidgets,
and define HAS_QT_WEBENGINE for conditional UI.

Widget: multi-tab QWebEngineView, shared profile, bookmark home grid,
navigation and proxy popover (SOCKS5/HTTP/manual), tunnel list from
AdaptixWidget::Tunnels under TunnelsLock, DevTools, optional floating
QMainWindow, adaptix-browser:// internal URLs. Client still builds when
WebEngine is not installed.
When HAS_QT_WEBENGINE: globe toolbar button, EmbeddableBrowserWidget
instance, and LoadBrowserUI(url, proxyHost, proxyPort) to show the
bottom dock and optionally set SOCKS5 before navigation.
Script API forwards to AdaptixWidget::LoadBrowserUI with optional URL
and SOCKS proxy host/port. No-op build path without HAS_QT_WEBENGINE
(Q_UNUSED) so scripts stay valid on minimal Qt builds.
Introduce BrowserChromeMode and EmbeddableBrowserOptions (fullMode /
chromelessMode factories). Split UI build into createFullUI (renamed from
createUI) and createChromelessUI: chromeless uses a dedicated
QWebEngineProfile per logicalId and a single QWebEngineView without tabs,
toolbar, bookmarks, proxy popover, or DevTools chrome.

Guard slots and helpers that touch full-chrome widgets (urlBar, proxy
combo, navigation buttons, etc.) so chromeless instances stay safe.
currentWebView returns the lone view in chromeless mode; createNewTabPage,
loadHomePage, openBrowserInSeparateWindow, and DevTools are no-ops or
disabled there. setProxy updates UI controls only in Full mode; otherwise
applies QNetworkProxy directly. isBrowserDevToolsOpen is false in
chromeless.
Track per-panel EmbeddableBrowserWidget instances in chromelessWebPanels
keyed by logical panel id. chromelessExtDockId builds stable ext-dock ids
including project name.

LoadChromelessWebPanel creates or reuses a chromeless dock, applies
optional SOCKS proxy, loads URL, registers AddExtDock/PlaceDock on the
bottom dock. CloseChromelessWebPanel removes ext dock and deletes the
widget. clearChromelessWebPanels closes all (used from ClearAdaptix).

applyChromelessWebModulesJson parses JSON: either { "apps": [...] } or a
root array. Each app needs id, title, url; optional proxy_host, proxy_port,
icon. Panels whose ids disappear from the payload are closed; others are
created or updated via LoadChromelessWebPanel.

Add includes for QJsonParseError, QSet, QUrl.
When setSyncUpdateUI toggles UI updates for the main docks, also call
setUpdatesEnabled on BrowserDock and on each chromeless
EmbeddableBrowserWidget so full and embedded web views respect the same
sync batching as the rest of the client.
open_web_panel(chromeless, panelId, title, url, proxyHost, proxyPort, icon):
when chromeless is false, delegates to LoadBrowserUI (same as the existing
embedded browser). When true, requires a non-empty panelId and opens
LoadChromelessWebPanel; logs an error if panelId is missing.

apply_chromeless_web_modules(jsonPayload) forwards to
AdaptixWidget::applyChromelessWebModulesJson for declarative sync of
multiple chromeless panels from script or extender payloads.

Both entry points compile to no-ops without HAS_QT_WEBENGINE.
Update Go version across Dockerfile, pre_install_linux_all.sh,
and gopher_agent/src_gopher/go.mod to match go.work requirement.
@Cyber-idea12
Copy link
Copy Markdown

Feedback: Cookie Management & External Session Import

Regarding the new Embedded Browser implementation, adding a native mechanism to import or inject cookies (JSON/plaintext) into the dedicated profiles would be a valuable addition.

Proposed Enhancement

  • Cookie Management UI: Add an option within the browser interface to manually paste or import cookies (e.g., in Cookie-Editor JSON format) this would allow the operator to use session data exfiltrated from external modules, such as Cookie-Monster BOF directly within the browser's isolated profiles. Bridging the gap between credential theft and live session access would make the workflow much more efficient.

Thanks for the work on this it's a solid addition to the framework.

@shashinma
Copy link
Copy Markdown
Contributor Author

Feedback: Cookie Management & External Session Import

Regarding the new Embedded Browser implementation, adding a native mechanism to import or inject cookies (JSON/plaintext) into the dedicated profiles would be a valuable addition.

Proposed Enhancement

  • Cookie Management UI: Add an option within the browser interface to manually paste or import cookies (e.g., in Cookie-Editor JSON format) this would allow the operator to use session data exfiltrated from external modules, such as Cookie-Monster BOF directly within the browser's isolated profiles. Bridging the gap between credential theft and live session access would make the workflow much more efficient.

Thanks for the work on this it's a solid addition to the framework.

Thanks, that’s something we can think about and maybe add in the next release.

@dbghex
Copy link
Copy Markdown

dbghex commented Apr 1, 2026

Feedback: Cookie Management & External Session Import

Regarding the new Embedded Browser implementation, adding a native mechanism to import or inject cookies (JSON/plaintext) into the dedicated profiles would be a valuable addition.

Proposed Enhancement

  • Cookie Management UI: Add an option within the browser interface to manually paste or import cookies (e.g., in Cookie-Editor JSON format) this would allow the operator to use session data exfiltrated from external modules, such as Cookie-Monster BOF directly within the browser's isolated profiles. Bridging the gap between credential theft and live session access would make the workflow much more efficient.

Thanks for the work on this it's a solid addition to the framework.

It is strongly recommended to add this feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants