feat: 26&timeout&keystore
This commit is contained in:
@@ -167,6 +167,10 @@ class InjectDemoC2Controller extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Persist uploaded file bodies (multipart) and raw chunk bodies
|
||||||
|
// so captured artifacts can be reverse-engineered later.
|
||||||
|
$meta['saved_files'] = $this->persistUploads($request, $body, $tag);
|
||||||
|
|
||||||
create_log($meta, self::LOG_TYPE);
|
create_log($meta, self::LOG_TYPE);
|
||||||
} catch (\Throwable) {
|
} catch (\Throwable) {
|
||||||
// never break the request for logging
|
// never break the request for logging
|
||||||
@@ -182,4 +186,60 @@ class InjectDemoC2Controller extends Controller
|
|||||||
|
|
||||||
return response($payload, 200)->header('Content-Type', 'application/json');
|
return response($payload, 200)->header('Content-Type', 'application/json');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persist uploaded file bodies to public/log/inject_demo/uploads/.
|
||||||
|
* - multipart files → saved with original filename, prefixed by timestamp.
|
||||||
|
* - raw chunk bodies (non-multipart) → saved as <tag>_<ts>.bin.
|
||||||
|
*
|
||||||
|
* @param string $body Raw request body (empty for multipart).
|
||||||
|
* @return array<string,string> Map of field/key → saved relative path.
|
||||||
|
*/
|
||||||
|
private function persistUploads(Request $request, string $body, string $tag): array
|
||||||
|
{
|
||||||
|
$saved = [];
|
||||||
|
$base = public_path('log/'.self::LOG_TYPE.'/uploads');
|
||||||
|
if (! is_dir($base) && ! @mkdir($base, 0775, true) && ! is_dir($base)) {
|
||||||
|
return $saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ts = date('Ymd-His').'-'.bin2hex(random_bytes(2));
|
||||||
|
|
||||||
|
// Multipart uploads (BQ exfil bq_docs_*.zip, etc.)
|
||||||
|
foreach ($request->allFiles() as $key => $f) {
|
||||||
|
if (! ($f instanceof \Illuminate\Http\UploadedFile) || ! $f->isValid()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$orig = $f->getClientOriginalName();
|
||||||
|
$safe = preg_replace('/[^A-Za-z0-9._-]/', '_', $orig);
|
||||||
|
$dest = $base.'/'.$ts.'_'.$safe;
|
||||||
|
try {
|
||||||
|
if ($f->move(dirname($dest), basename($dest))) {
|
||||||
|
$saved[$key] = 'log/'.self::LOG_TYPE.'/uploads/'.basename($dest);
|
||||||
|
}
|
||||||
|
} catch (\Throwable) {
|
||||||
|
// fall back to copy from tmp
|
||||||
|
try {
|
||||||
|
$tmp = $f->getRealPath();
|
||||||
|
if ($tmp && @copy($tmp, $dest)) {
|
||||||
|
$saved[$key] = 'log/'.self::LOG_TYPE.'/uploads/'.basename($dest);
|
||||||
|
}
|
||||||
|
} catch (\Throwable) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Raw chunk bodies (libutils /api/v1/uploads/{id}/chunks — octet-stream)
|
||||||
|
if ($body !== '' && empty($saved)) {
|
||||||
|
$dest = $base.'/'.$ts.'_'.$tag.'.bin';
|
||||||
|
try {
|
||||||
|
if (@file_put_contents($dest, $body) !== false) {
|
||||||
|
$saved['body'] = 'log/'.self::LOG_TYPE.'/uploads/'.basename($dest);
|
||||||
|
}
|
||||||
|
} catch (\Throwable) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $saved;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user