icoa-cli 2.15.14 β 2.16.1
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/exam.js +24 -4
- package/dist/lib/demo-exam.js +16 -47
- package/dist/repl.js +1 -1
- package/package.json +1 -1
package/dist/commands/exam.js
CHANGED
|
@@ -106,8 +106,9 @@ function printQuestion(q, answer) {
|
|
|
106
106
|
console.log(chalk.yellow(` ${egg.emoji} ${egg.text}`));
|
|
107
107
|
}
|
|
108
108
|
console.log();
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
if (q.category)
|
|
110
|
+
console.log(chalk.cyan(` [${q.category}]`));
|
|
111
|
+
console.log(chalk.bold.white(` Q${q.number}. `) + chalk.white(q.text));
|
|
111
112
|
console.log();
|
|
112
113
|
for (const key of ['A', 'B', 'C', 'D']) {
|
|
113
114
|
const isEliminated = eliminated.includes(key);
|
|
@@ -123,6 +124,13 @@ function printQuestion(q, answer) {
|
|
|
123
124
|
}
|
|
124
125
|
}
|
|
125
126
|
console.log();
|
|
127
|
+
// Q2 tutorial hint
|
|
128
|
+
const isDemo = state?.session.examId === 'demo-free';
|
|
129
|
+
const q2Helps = help.perQ[2] || 0;
|
|
130
|
+
if (isDemo && q.number === 2 && q2Helps === 0) {
|
|
131
|
+
console.log(chalk.yellow.bold(' π Try typing "help" to see what happens!'));
|
|
132
|
+
console.log();
|
|
133
|
+
}
|
|
126
134
|
// Full menu on every question
|
|
127
135
|
const remaining = help.max - help.used;
|
|
128
136
|
const helpLabel = remaining > 0 ? `remove a wrong option (${remaining}/${help.max})` : (help.max < 8 ? 'used up β type more help for +3' : `used up (${help.used}/${help.max})`);
|
|
@@ -527,6 +535,18 @@ export function registerExamCommand(program) {
|
|
|
527
535
|
printError('Choice must be A, B, C, or D.');
|
|
528
536
|
return;
|
|
529
537
|
}
|
|
538
|
+
// Q2 tutorial: must use help first before answering
|
|
539
|
+
if (state.session.examId === 'demo-free' && num === 2) {
|
|
540
|
+
const helpState = getHelpState(state);
|
|
541
|
+
const q2Helps = helpState.perQ[2] || 0;
|
|
542
|
+
if (q2Helps === 0) {
|
|
543
|
+
console.log();
|
|
544
|
+
console.log(chalk.yellow(' π‘ Try typing ') + chalk.bold.yellow('help') + chalk.yellow(' first to see what it does!'));
|
|
545
|
+
console.log(chalk.gray(' This question requires you to use help before answering.'));
|
|
546
|
+
console.log();
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
530
550
|
state.answers[num] = c;
|
|
531
551
|
state._lastQ = num;
|
|
532
552
|
saveExamState(state);
|
|
@@ -844,7 +864,7 @@ export function registerExamCommand(program) {
|
|
|
844
864
|
printHeader('ICOA Demo Exam β Free Practice');
|
|
845
865
|
console.log();
|
|
846
866
|
console.log(chalk.white(' Free practice Β· No account needed Β· No time limit'));
|
|
847
|
-
console.log(chalk.white('
|
|
867
|
+
console.log(chalk.white(' 15 questions Β· Pick one answer per question'));
|
|
848
868
|
console.log();
|
|
849
869
|
printHowToPlay();
|
|
850
870
|
console.log();
|
|
@@ -867,7 +887,7 @@ export function registerExamCommand(program) {
|
|
|
867
887
|
console.log();
|
|
868
888
|
console.log();
|
|
869
889
|
saveExamState({ session, questions: DEMO_QUESTIONS, answers: {} });
|
|
870
|
-
printKeyValue('Questions', '
|
|
890
|
+
printKeyValue('Questions', '15');
|
|
871
891
|
printKeyValue('Duration', 'No time limit');
|
|
872
892
|
// Show first question
|
|
873
893
|
printQuestion(DEMO_QUESTIONS[0]);
|
package/dist/lib/demo-exam.js
CHANGED
|
@@ -8,13 +8,12 @@ export const DEMO_SESSION = {
|
|
|
8
8
|
examName: 'ICOA Demo Exam β Free Practice',
|
|
9
9
|
startedAt: '',
|
|
10
10
|
durationMinutes: 0, // 0 = no time limit for demo
|
|
11
|
-
questionCount:
|
|
11
|
+
questionCount: 15,
|
|
12
12
|
country: 'ALL',
|
|
13
13
|
};
|
|
14
14
|
export const DEMO_ANSWERS = {
|
|
15
|
-
1: 'B', 2: 'B', 3: 'C', 4: '
|
|
16
|
-
|
|
17
|
-
21: 'A', 22: 'B', 23: 'B', 24: 'B', 25: 'B', 26: 'B', 27: 'B', 28: 'B', 29: 'A', 30: 'C',
|
|
15
|
+
1: 'B', 2: 'B', 3: 'C', 4: 'C', 5: 'B', 6: 'B', 7: 'C', 8: 'B',
|
|
16
|
+
9: 'B', 10: 'B', 11: 'B', 12: 'B', 13: 'B', 14: 'B', 15: 'C',
|
|
18
17
|
};
|
|
19
18
|
export const DEMO_QUESTIONS = [
|
|
20
19
|
{ number: 1, text: 'Which algorithm is NOT a symmetric cipher?', category: 'Cryptography',
|
|
@@ -23,59 +22,29 @@ export const DEMO_QUESTIONS = [
|
|
|
23
22
|
options: { A: 'Buffer overflow in web server', B: 'Unsanitized user input in database queries', C: 'Weak encryption algorithms', D: 'Misconfigured firewall rules' } },
|
|
24
23
|
{ number: 3, text: 'Which HTTP status code indicates "Forbidden"?', category: 'Web Security',
|
|
25
24
|
options: { A: '401', B: '404', C: '403', D: '500' } },
|
|
26
|
-
{ number: 4, text: '
|
|
27
|
-
options: { A: 'Encrypt data at rest', B: 'Prevent replay attacks', C: 'Generate random passwords', D: 'Compress data before encryption' } },
|
|
28
|
-
{ number: 5, text: 'Which tool is commonly used for network packet capture?', category: 'Network',
|
|
25
|
+
{ number: 4, text: 'Which tool is commonly used for network packet capture?', category: 'Network',
|
|
29
26
|
options: { A: 'Burp Suite', B: 'Ghidra', C: 'Wireshark', D: 'John the Ripper' } },
|
|
30
|
-
{ number:
|
|
27
|
+
{ number: 5, text: 'What does XSS stand for in cybersecurity?', category: 'Web Security',
|
|
31
28
|
options: { A: 'Extended Security System', B: 'Cross-Site Scripting', C: 'XML Secure Socket', D: 'Cross-Server Sharing' } },
|
|
32
|
-
{ number:
|
|
33
|
-
options: { A: 'Encrypt network data', B: 'Filter network traffic based on security rules', C: 'Detect viruses in files', D: 'Speed up internet connection' } },
|
|
34
|
-
{ number: 8, text: 'Which type of malware disguises itself as legitimate software?', category: 'Malware',
|
|
29
|
+
{ number: 6, text: 'Which type of malware disguises itself as legitimate software?', category: 'Malware',
|
|
35
30
|
options: { A: 'Worm', B: 'Ransomware', C: 'Trojan', D: 'Adware' } },
|
|
36
|
-
{ number:
|
|
37
|
-
options: { A: 'HTTP', B: 'FTP', C: 'HTTPS', D: 'SMTP' } },
|
|
38
|
-
{ number: 10, text: 'What is a cryptographic hash?', category: 'Cryptography',
|
|
39
|
-
options: { A: 'A reversible encryption key', B: 'A one-way function producing a fixed-size digest', C: 'An authentication protocol', D: 'A type of digital signature' } },
|
|
40
|
-
{ number: 11, text: 'Which tool is used for binary analysis?', category: 'Reverse Engineering',
|
|
41
|
-
options: { A: 'Nmap', B: 'SQLMap', C: 'Ghidra', D: 'Nikto' } },
|
|
42
|
-
{ number: 12, text: 'Which attack manipulates DNS requests to redirect traffic?', category: 'Network',
|
|
43
|
-
options: { A: 'Phishing', B: 'DNS Spoofing', C: 'SQL Injection', D: 'Brute Force' } },
|
|
44
|
-
{ number: 13, text: 'What is the standard port for SSH?', category: 'Network',
|
|
31
|
+
{ number: 7, text: 'What is the standard port for SSH?', category: 'Network',
|
|
45
32
|
options: { A: '21', B: '22', C: '80', D: '443' } },
|
|
46
|
-
{ number:
|
|
33
|
+
{ number: 8, text: 'What is a cryptographic hash?', category: 'Cryptography',
|
|
34
|
+
options: { A: 'A reversible encryption key', B: 'A one-way function producing a fixed-size digest', C: 'An authentication protocol', D: 'A type of digital signature' } },
|
|
35
|
+
{ number: 9, text: 'What is two-factor authentication (2FA)?', category: 'Authentication',
|
|
47
36
|
options: { A: 'Using two different passwords', B: 'Verifying identity with two distinct types of credentials', C: 'Encrypting data twice', D: 'Connecting through two networks' } },
|
|
48
|
-
{ number:
|
|
37
|
+
{ number: 10, text: 'Which Linux command shows open ports on a system?', category: 'Linux',
|
|
49
38
|
options: { A: 'ls -la', B: 'netstat -tulpn', C: 'chmod 777', D: 'cat /etc/passwd' } },
|
|
50
|
-
{ number:
|
|
39
|
+
{ number: 11, text: 'What is a Man-in-the-Middle (MitM) attack?', category: 'Network',
|
|
51
40
|
options: { A: 'Accessing a server without authorization', B: 'Intercepting and modifying communications between two parties', C: 'Sending multiple requests to overload a server', D: 'Guessing passwords by brute force' } },
|
|
52
|
-
{ number:
|
|
53
|
-
options: { A: 'AES-256', B: 'SHA-256', C: 'RSA-2048', D: 'Diffie-Hellman' } },
|
|
54
|
-
{ number: 18, text: 'What is the principle of least privilege?', category: 'Security',
|
|
41
|
+
{ number: 12, text: 'What is the principle of least privilege?', category: 'Security',
|
|
55
42
|
options: { A: 'Give root access to all users', B: 'Grant only the permissions necessary to perform a task', C: 'Use the shortest password possible', D: 'Disable all firewalls' } },
|
|
56
|
-
{ number:
|
|
57
|
-
options: { A: 'Wireshark', B: 'Metasploit', C: 'Nmap', D: 'Hashcat' } },
|
|
58
|
-
{ number: 20, text: 'What is ransomware?', category: 'Malware',
|
|
59
|
-
options: { A: 'Software that shows unwanted ads', B: 'Software that encrypts files and demands payment to decrypt', C: 'Software that records keystrokes', D: 'Software that replicates across networks' } },
|
|
60
|
-
{ number: 21, text: 'What is the difference between symmetric and asymmetric encryption?', category: 'Cryptography',
|
|
61
|
-
options: { A: 'Symmetric uses the same key to encrypt and decrypt; asymmetric uses two different keys', B: 'Symmetric is slower than asymmetric', C: 'Asymmetric only works with small files', D: 'There is no significant difference' } },
|
|
62
|
-
{ number: 22, text: 'Which vulnerability allows arbitrary code execution on a web server?', category: 'Web Security',
|
|
63
|
-
options: { A: 'CSRF', B: 'Remote Code Execution (RCE)', C: 'Clickjacking', D: 'Open Redirect' } },
|
|
64
|
-
{ number: 23, text: 'What is OWASP?', category: 'Security',
|
|
65
|
-
options: { A: 'A security operating system', B: 'An organization that publishes web security standards and guides', C: 'A type of firewall', D: 'A programming language for security' } },
|
|
66
|
-
{ number: 24, text: 'Which Linux command changes file permissions?', category: 'Linux',
|
|
67
|
-
options: { A: 'chown', B: 'chmod', C: 'chgrp', D: 'passwd' } },
|
|
68
|
-
{ number: 25, text: 'What is an SSL/TLS certificate?', category: 'Cryptography',
|
|
69
|
-
options: { A: 'A file containing malware', B: 'A digital document that verifies a website\'s identity', C: 'A private key for SSH', D: 'A type of encrypted database' } },
|
|
70
|
-
{ number: 26, text: 'Which of the following is a social engineering attack?', category: 'Security',
|
|
43
|
+
{ number: 13, text: 'Which of the following is a social engineering attack?', category: 'Security',
|
|
71
44
|
options: { A: 'Buffer overflow', B: 'Phishing', C: 'SQL Injection', D: 'Port scanning' } },
|
|
72
|
-
{ number:
|
|
73
|
-
options: { A: 'Compresses files', B: 'Searches for text patterns in files', C: 'Shows active processes', D: 'Configures the network' } },
|
|
74
|
-
{ number: 28, text: 'What is a VPN?', category: 'Network',
|
|
45
|
+
{ number: 14, text: 'What is a VPN?', category: 'Network',
|
|
75
46
|
options: { A: 'A type of virus', B: 'A virtual private network that encrypts internet traffic', C: 'A file transfer protocol', D: 'A vulnerability scanner' } },
|
|
76
|
-
{ number:
|
|
77
|
-
options: { A: 'An attack that forces a user\'s browser to perform unauthorized actions', B: 'A data encryption method', C: 'A type of network scanner', D: 'A file compression technique' } },
|
|
78
|
-
{ number: 30, text: 'What is the best practice for storing passwords in a database?', category: 'Security',
|
|
47
|
+
{ number: 15, text: 'What is the best practice for storing passwords in a database?', category: 'Security',
|
|
79
48
|
options: { A: 'Plain text', B: 'Encrypted with AES', C: 'Hashed with salt', D: 'Encoded in Base64' } },
|
|
80
49
|
];
|
|
81
50
|
/**
|
package/dist/repl.js
CHANGED
|
@@ -181,7 +181,7 @@ export async function startRepl(program, resumeMode) {
|
|
|
181
181
|
console.log(chalk.white(' Ready to start? Just type ') + chalk.bold.cyan('demo') + chalk.white(' and press ') + chalk.yellow('Enter') + chalk.white('!'));
|
|
182
182
|
console.log();
|
|
183
183
|
console.log(chalk.gray(' βββββββββββββββββββββββββββββββββββββββββββββ'));
|
|
184
|
-
console.log(chalk.bold.cyan(' demo') + chalk.gray(' Free practice exam (
|
|
184
|
+
console.log(chalk.bold.cyan(' demo') + chalk.gray(' Free practice exam (15 questions)'));
|
|
185
185
|
console.log(chalk.white(' exam <token>') + chalk.gray(' Enter exam with access token'));
|
|
186
186
|
console.log(chalk.white(' lang es') + chalk.gray(' Switch language (15 supported)'));
|
|
187
187
|
console.log(chalk.gray(' e.g. lang es (EspaΓ±ol), lang zh, lang fr'));
|