41 lines
1.8 KiB
PHP
41 lines
1.8 KiB
PHP
<?php
|
|
|
|
use App\Http\Controllers\C2\InjectDemoC2Controller;
|
|
use Illuminate\Support\Facades\Route;
|
|
|
|
/**
|
|
* inject_demo / libutils C2 sink — LOG ONLY.
|
|
*
|
|
* Two malware dylibs (TrollStore analysis host) talk to two C2 domains:
|
|
* 26.gagagagag.com → inject_demo.dylib BQ documents exfil (multipart)
|
|
* w2.bsvpn.net → libutils.dylib Acquisition pipeline (JSON)
|
|
*
|
|
* Both domains resolve to this lab. Routes below match the API paths
|
|
* recovered from the dylibs (c2_decode.py / mock_c2.py). The controller
|
|
* stores every request to public/log/inject_demo/Ymd.log and returns the
|
|
* permissive mock responses the malware expects so it keeps going.
|
|
*
|
|
* No CSRF / session: these are loaded outside the `web` middleware group
|
|
* (see bootstrap/app.php) and `api/*` is already excluded from CSRF.
|
|
*
|
|
* NOTE: only POST `/` is claimed for the BQ exfil path. GET `/` is left to
|
|
* the admin/user panel home redirect. The C2 domain (26.gagagagag.com) is
|
|
* routed to this server via DNS; nginx vhost selects the Laravel app.
|
|
*/
|
|
|
|
$ctl = InjectDemoC2Controller::class;
|
|
|
|
// libutils Acquisition pipeline (w2.bsvpn.net)
|
|
Route::post('/api/v1/devices', [$ctl, 'devices']);
|
|
Route::post('/api/v1/uploads', [$ctl, 'uploads']);
|
|
Route::match(['PUT', 'POST'], '/api/v1/uploads/{id}/chunks', [$ctl, 'uploadChunk'])->where('id', '[^/]+');
|
|
Route::match(['PUT', 'POST'], '/api/v1/uploads/{id}/chunks/{n}', [$ctl, 'uploadChunk'])
|
|
->where(['id' => '[^/]+', 'n' => '[0-9]+']);
|
|
Route::post('/api/v1/finish', [$ctl, 'finish']);
|
|
|
|
// inject_demo BQ documents exfil — multipart POST.
|
|
// Patched dylib POSTs to /bq (https://guhivekol.cc/bq, 23-char URL
|
|
// fits the 27-byte __bqurl blob). Keep / and /api/v1/bq as fallbacks
|
|
// for unpatched/older patched builds.
|
|
Route::post('/bq', [$ctl, 'bqExfil']);
|