icoa-cli 2.19.29 → 2.19.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/ai4ctf.js +73 -5
- package/package.json +1 -1
package/dist/commands/ai4ctf.js
CHANGED
|
@@ -31,9 +31,70 @@ function drawTokenBar() {
|
|
|
31
31
|
console.log(chalk.gray(' Tokens: ') + color('█'.repeat(filled)) + chalk.gray('░'.repeat(empty)) + chalk.gray(` ${used}/${cap} (${pct}%)`));
|
|
32
32
|
}
|
|
33
33
|
const DEMO_FLAG = 'icoa{w3lc0me_2_ai4ctf}';
|
|
34
|
+
// Scripted hints for the built-in Base64 demo challenge. The hint philosophy:
|
|
35
|
+
// - a: nudge you toward the fingerprint (padding, charset).
|
|
36
|
+
// - b: tell you the encoding name, nothing more. No shell command.
|
|
37
|
+
// - c: for simple challenges, c deliberately adds no new info — hint b was
|
|
38
|
+
// already enough. Instead c explains the hint principle and reminds the
|
|
39
|
+
// user how to run a shell command inside ai4ctf (the `!` prefix).
|
|
40
|
+
// This mirrors real competition behavior where trivial challenges cap at hint b.
|
|
41
|
+
const DEMO_HINTS = {
|
|
42
|
+
a: [
|
|
43
|
+
'The string ends with "==" and uses only letters, digits, "+", "/", and "=".',
|
|
44
|
+
'That pattern is a fingerprint — you have seen it before.',
|
|
45
|
+
'Where is "=" typically used as padding?',
|
|
46
|
+
],
|
|
47
|
+
b: [
|
|
48
|
+
'This is Base64 encoded. Decode the string to find the flag.',
|
|
49
|
+
],
|
|
50
|
+
c: [
|
|
51
|
+
'Hints never give you the answer directly — they only point you in the right direction.',
|
|
52
|
+
'For simple challenges like this one, hint c adds nothing extra:',
|
|
53
|
+
'hint b already tells you everything you need.',
|
|
54
|
+
'',
|
|
55
|
+
'If you do not remember how to decode Base64, ask your AI teammate —',
|
|
56
|
+
'just type a question like: how do I decode Base64 on the command line?',
|
|
57
|
+
'',
|
|
58
|
+
'To run a shell command inside ai4ctf, prefix it with "!". For example:',
|
|
59
|
+
'',
|
|
60
|
+
' !echo aWNvYXt3M2xjMG1lXzJfYWk0Y3RmfQ== | base64 -d',
|
|
61
|
+
],
|
|
62
|
+
};
|
|
63
|
+
function showDemoHint(tier) {
|
|
64
|
+
const title = tier === 'a' ? t('ai4ctfHintA') : tier === 'b' ? t('ai4ctfHintB') : t('ai4ctfHintC');
|
|
65
|
+
const tierLabel = `Hint ${tier.toUpperCase()}`;
|
|
66
|
+
const color = tier === 'a' ? chalk.green : tier === 'b' ? chalk.yellow : chalk.red;
|
|
67
|
+
console.log();
|
|
68
|
+
console.log(color.bold(` ▸ ${tierLabel} `) + chalk.gray(title));
|
|
69
|
+
console.log();
|
|
70
|
+
for (const line of DEMO_HINTS[tier]) {
|
|
71
|
+
if (line === '')
|
|
72
|
+
console.log();
|
|
73
|
+
else
|
|
74
|
+
console.log(chalk.white(' ' + line));
|
|
75
|
+
}
|
|
76
|
+
console.log();
|
|
77
|
+
if (tier === 'a') {
|
|
78
|
+
console.log(chalk.gray(' Stuck? Try: ') + chalk.cyan('hint b'));
|
|
79
|
+
console.log();
|
|
80
|
+
}
|
|
81
|
+
else if (tier === 'b') {
|
|
82
|
+
console.log(chalk.gray(' Really stuck? Try: ') + chalk.cyan('hint c'));
|
|
83
|
+
console.log();
|
|
84
|
+
}
|
|
85
|
+
// No trailing CTA after hint c — the content itself explains everything.
|
|
86
|
+
}
|
|
34
87
|
export async function handleChatMessage(input) {
|
|
35
88
|
if (!chatSession)
|
|
36
89
|
return 'exit';
|
|
90
|
+
// Scripted demo hints — intercept before the AI chat so that typing
|
|
91
|
+
// `hint a` / `hint b` / `hint c` behaves like a real competition command
|
|
92
|
+
// instead of becoming a generic AI chat turn.
|
|
93
|
+
const hintMatch = input.trim().toLowerCase().match(/^hint\s+([abc])$/);
|
|
94
|
+
if (hintMatch) {
|
|
95
|
+
showDemoHint(hintMatch[1]);
|
|
96
|
+
return 'continue';
|
|
97
|
+
}
|
|
37
98
|
// Flag submission
|
|
38
99
|
const submitMatch = input.match(/^submit\s+(.+)/i);
|
|
39
100
|
if (submitMatch) {
|
|
@@ -197,13 +258,20 @@ export function registerAi4ctfCommand(program) {
|
|
|
197
258
|
console.log(chalk.gray(` ${t('ai4ctfHintCUses')}`));
|
|
198
259
|
console.log();
|
|
199
260
|
console.log(chalk.gray(' ─────────────────────────────────────────'));
|
|
200
|
-
console.log(chalk.white(
|
|
201
|
-
console.log(chalk.gray(
|
|
202
|
-
console.log(chalk.gray(
|
|
261
|
+
console.log(chalk.bold.white(' 👉 New here? Start with the hints in order:'));
|
|
262
|
+
console.log(' ' + chalk.cyan('hint a') + chalk.gray(' → nudge'));
|
|
263
|
+
console.log(' ' + chalk.cyan('hint b') + chalk.gray(' → technique'));
|
|
264
|
+
console.log(' ' + chalk.cyan('hint c') + chalk.gray(' → principle + shell reminder'));
|
|
265
|
+
console.log(chalk.gray(' (hints guide you — they never give the answer directly)'));
|
|
266
|
+
console.log();
|
|
267
|
+
console.log(chalk.white(' Or chat freely with your AI teammate — ask anything'));
|
|
268
|
+
console.log(chalk.gray(' about the challenge. Example: ') + chalk.white('"what encoding is this?"'));
|
|
203
269
|
console.log();
|
|
204
270
|
console.log(chalk.yellow(` ${t('ai4ctfCommands')}`));
|
|
205
|
-
console.log(chalk.white('
|
|
206
|
-
console.log(chalk.white('
|
|
271
|
+
console.log(chalk.white(' hint a / b / c ') + chalk.gray('pre-written hints (safe to use)'));
|
|
272
|
+
console.log(chalk.white(' submit <flag> ') + chalk.gray(t('ai4ctfSubmitCmd')));
|
|
273
|
+
console.log(chalk.white(' !<shell cmd> ') + chalk.gray('run a shell command'));
|
|
274
|
+
console.log(chalk.gray(' e.g. ') + chalk.white('!echo aWNv... | base64 -d'));
|
|
207
275
|
console.log(chalk.gray(` exit ${t('ai4ctfEndSession')}`));
|
|
208
276
|
console.log();
|
|
209
277
|
drawTokenBar();
|