|
5 | 5 |
|
6 | 6 | const Promise = require('bluebird')
|
7 | 7 | const calculateScore = require('../calculateScore')
|
8 |
| -const calculateHintCost = require('../calculateHintCost') |
| 8 | +// const calculateHintCost = require('../calculateHintCost') |
9 | 9 | const hmacSha1 = require('../hmac')
|
10 | 10 | const options = require('../options')
|
11 | 11 |
|
12 | 12 | function createCtfdExport (challenges, { insertHints, insertHintUrls, insertHintSnippets, ctfKey, vulnSnippets }) {
|
13 |
| - function insertChallenge (data, challenge) { |
14 |
| - const score = calculateScore(challenge.difficulty) |
15 |
| - challenge.description = challenge.description.replace('`xss`', '`xss`') |
16 |
| - data.challenges.results.push( |
17 |
| - { |
18 |
| - id: challenge.id, |
19 |
| - name: challenge.name, |
20 |
| - description: challenge.description + ' (Difficulty Level: ' + challenge.difficulty + ')', |
21 |
| - max_attempts: 0, |
22 |
| - value: score, |
23 |
| - category: challenge.category, |
24 |
| - type: 'standard', |
25 |
| - state: 'visible', |
26 |
| - next_id: null // TODO Use "tutorialOrder" to recommend order of first challenges; leave null for rest |
27 |
| - } |
28 |
| - ) |
29 |
| - } |
30 |
| - |
31 |
| - function insertKey ({ flagKeys }, { id, name }) { |
32 |
| - flagKeys.results.push( |
33 |
| - { |
34 |
| - id, |
35 |
| - challenge_id: id, |
36 |
| - type: 'static', |
37 |
| - content: hmacSha1(ctfKey, name), |
38 |
| - data: null |
39 |
| - } |
40 |
| - ) |
41 |
| - } |
42 |
| - |
43 |
| - function insertTextHint ({ hints }, challenge) { |
44 |
| - hints.results.push( |
45 |
| - { |
46 |
| - id: challenge.id, |
47 |
| - type: 'standard', |
48 |
| - challenge_id: challenge.id, |
49 |
| - content: challenge.hint, |
50 |
| - cost: calculateHintCost(challenge, insertHints) |
51 |
| - } |
52 |
| - ) |
53 |
| - } |
54 |
| - |
55 |
| - function insertHintUrl ({ hints }, challenge, hasTextHintPrerequisite) { |
56 |
| - hints.results.push( |
57 |
| - { |
58 |
| - id: 10000 + challenge.id, |
59 |
| - type: 'standard', |
60 |
| - challenge_id: challenge.id, |
61 |
| - content: challenge.hintUrl, |
62 |
| - cost: calculateHintCost(challenge, insertHintUrls), |
63 |
| - requirements: hasTextHintPrerequisite ? { prerequisites: [challenge.id] } : null |
64 |
| - } |
65 |
| - ) |
66 |
| - } |
67 |
| - |
68 |
| - function insertHintSnippet ({ hints }, challenge, snippet, hasTextHintPrerequisite, hasHintUrlPrerequisite) { |
69 |
| - hints.results.push( |
70 |
| - { |
71 |
| - id: 20000 + challenge.id, |
72 |
| - type: 'standard', |
73 |
| - challenge_id: challenge.id, |
74 |
| - content: '<pre><code>' + snippet + '</code></pre>', |
75 |
| - cost: calculateHintCost(challenge, insertHintSnippets), |
76 |
| - requirements: hasTextHintPrerequisite ? (hasHintUrlPrerequisite ? { prerequisites: [challenge.id, 10000 + challenge.id] } : { prerequisites: [challenge.id] }) : (hasHintUrlPrerequisite ? { prerequisites: [10000 + challenge.id] } : null) |
77 |
| - } |
78 |
| - ) |
| 13 | + function insertChallengeHints (challenge) { |
| 14 | + const hints = [] |
| 15 | + if (challenge.hint && insertHints !== options.noTextHints) { |
| 16 | + hints.push(challenge.hint.replaceAll('"', '""').replaceAll(',', '٬')) |
| 17 | + } |
| 18 | + if (challenge.hintUrl && insertHintUrls !== options.noHintUrls) { |
| 19 | + hints.push(challenge.hintUrl) |
| 20 | + } |
| 21 | + if (vulnSnippets[challenge.key] && insertHintSnippets !== options.noHintSnippets) { |
| 22 | + hints.push('<pre><code>' + vulnSnippets[challenge.key].replaceAll('"', '""').replaceAll(',', '٬') + '</code></pre>') |
| 23 | + } |
| 24 | + return (hints.length === 0 ? '' : `"${hints.join(',')}"`) |
79 | 25 | }
|
80 | 26 |
|
81 |
| - function insertTags ({ tags }, challenge) { |
82 |
| - if (!challenge.tags) { |
83 |
| - return |
| 27 | + /* |
| 28 | + function insertChallengeHintCosts (challenge) { |
| 29 | + const hintCosts = [] |
| 30 | + if (challenge.hint && insertHints !== options.noTextHints) { |
| 31 | + hintCosts.push(calculateHintCost(challenge, insertHints)) |
84 | 32 | }
|
85 |
| - tags.results.push( |
86 |
| - ...challenge.tags.split(',').map((tag, index) => { |
87 |
| - return { |
88 |
| - id: (challenge.id * 100) + index, |
89 |
| - challenge_id: challenge.id, |
90 |
| - value: tag |
91 |
| - } |
92 |
| - }) |
93 |
| - ) |
| 33 | + if (challenge.hintUrl && insertHintUrls !== options.noHintUrls) { |
| 34 | + hintCosts.push(calculateHintCost(challenge, insertHintUrls)) |
| 35 | + } |
| 36 | + if (vulnSnippets[challenge.key] && insertHintSnippets !== options.noHintSnippets) { |
| 37 | + hintCosts.push(calculateHintCost(challenge, insertHintSnippets)) |
| 38 | + } |
| 39 | + return (hintCosts.length === 0 ? '' : `"${hintCosts.join(',')}"`) |
94 | 40 | }
|
| 41 | +*/ |
95 | 42 |
|
96 | 43 | return new Promise((resolve, reject) => {
|
97 | 44 | try {
|
98 |
| - const data = { |
99 |
| - challenges: { results: [] }, |
100 |
| - hints: { results: [] }, |
101 |
| - flagKeys: { results: [] }, |
102 |
| - tags: { results: [] } |
103 |
| - } |
| 45 | + const data = [] |
104 | 46 | for (const key in challenges) {
|
105 | 47 | if (Object.prototype.hasOwnProperty.call(challenges, key)) {
|
106 | 48 | const challenge = challenges[key]
|
107 |
| - insertChallenge(data, challenge) |
108 |
| - insertKey(data, challenge) |
109 |
| - insertTags(data, challenge) |
110 |
| - if (challenge.hint && insertHints !== options.noTextHints) { |
111 |
| - insertTextHint(data, challenge) |
112 |
| - } |
113 |
| - if (challenge.hintUrl && insertHintUrls !== options.noHintUrls) { |
114 |
| - insertHintUrl(data, challenge, insertHints !== options.noTextHints) |
115 |
| - } |
116 |
| - if (vulnSnippets[challenge.key] && insertHintSnippets !== options.noHintSnippets) { |
117 |
| - insertHintSnippet(data, challenge, vulnSnippets[challenge.key], insertHints !== options.noTextHints, insertHintUrls !== options.noHintUrls) |
118 |
| - } |
| 49 | + data.push( |
| 50 | + { |
| 51 | + name: challenge.name, |
| 52 | + description: `"${challenge.description.replaceAll('"', '""')} (Difficulty Level: ${challenge.difficulty})"`, |
| 53 | + category: challenge.category, |
| 54 | + value: calculateScore(challenge.difficulty), |
| 55 | + type: 'standard', |
| 56 | + state: 'visible', |
| 57 | + max_attempts: 0, |
| 58 | + flags: hmacSha1(ctfKey, challenge.name), |
| 59 | + tags: challenge.tags ? `"${challenge.tags}"` : '', |
| 60 | + hints: insertChallengeHints(challenge), |
| 61 | + // hint_cost: insertChallengeHintCosts(challenge), |
| 62 | + type_data: '' |
| 63 | + } |
| 64 | + ) |
119 | 65 | }
|
120 | 66 | }
|
121 | 67 | resolve(data)
|
|
0 commit comments