Skip to content

Commit e21e043

Browse files
authored
Merge pull request #182 from OWASP/cvss-module
CVSS Lesson Module
2 parents 94ad6af + 5cd1e42 commit e21e043

28 files changed

+997
-24
lines changed

trainingportal/challenges.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ let init = async () => {
8484
let moduleDefinitions = getDefinitionsForModule(moduleId);
8585
var modulePath = getModulePath(moduleId);
8686
for(let level of moduleDefinitions){
87-
challengeDefinitions.push(level);
8887
for(let challenge of level.challenges){
8988
if(!util.isNullOrUndefined(challengeNames[challenge.id])){
9089
throw new Error(`Duplicate challenge id: '${challenge.id}'!`);
@@ -206,6 +205,7 @@ let getChallengeDefinitions = async (moduleId) => {
206205

207206
if(util.isNullOrUndefined(moduleId)) return [];
208207
if(util.isNullOrUndefined(modules[moduleId])) return [];
208+
if(!util.isNullOrUndefined(challengeDefinitions[moduleId])) return challengeDefinitions[moduleId];
209209

210210
var modulePath = getModulePath(moduleId);
211211
var moduleDefinitions = getDefinitionsForModule(moduleId);
@@ -224,12 +224,17 @@ let getChallengeDefinitions = async (moduleId) => {
224224
challenge.description = path.join(modulePath, description);
225225
}
226226
if(challenge.type === "quiz"){
227-
challenge.question = qna.getCode(challenge.id);
227+
if(util.isNullOrUndefined(challenge.options)){
228+
challenge.question = qna.getCode(challenge.id);
229+
}
230+
else if(!util.isNullOrUndefined(challenge.answer)){
231+
challenge.question = { "digest": qna.getDigest(challenge.answer)}
232+
}
228233
}
229234
}
230235
returnChallenges.push(level);
231236
}
232-
237+
challengeDefinitions[moduleId] = returnChallenges;
233238
return returnChallenges;
234239
}
235240

@@ -452,8 +457,8 @@ let apiChallengeCode = async (req) => {
452457
}
453458

454459
let answer = null;
455-
if(!util.isNullOrUndefined(req.body.answer)){
456-
answer = req.body.answer.trim();
460+
if(!util.isNullOrUndefined(req.body.answer) && typeof req.body.answer === "string"){
461+
answer = req.body.answer.trim().toLowerCase();
457462
}
458463

459464
if(util.isNullOrUndefined(challengeCode) ||

trainingportal/qna.js

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,12 @@ let getSecretText = (challengeId) => {
2525
return secretText.toUpperCase();
2626
}
2727

28+
let getDigest = (val) => {
29+
return crypto.createHash('sha256').update(val.trim().toLowerCase() + masterSalt).digest('hex');
30+
}
31+
2832
let getRes = (mes, code) => {
29-
let digest = crypto.createHash('sha256').update(mes.trim()+masterSalt).digest('hex');
33+
let digest = getDigest(mes);
3034
return res = {
3135
code:code,
3236
digest:digest,
@@ -227,6 +231,34 @@ let analysisEnc = (mes) => {
227231
return getRes(goldenKey, cipher);
228232
}
229233

234+
let cvss_3_score_1 = () => {
235+
return {"digest": getDigest("CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N")};
236+
}
237+
238+
let cvss_4_score_2 = () => {
239+
return {"digest": getDigest("CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N")};
240+
}
241+
242+
let cvss_5_chain = () => {
243+
return {"digest": getDigest("CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N")};
244+
}
245+
246+
let cvss_6_score_3 = () => {
247+
return {"digest": getDigest("CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N")};
248+
}
249+
250+
let cvss_7_score_4 = () => {
251+
return {"digest": getDigest("CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:H/SI:N/SA:N")};
252+
}
253+
254+
let cvss_8_score_5 = () => {
255+
return {"digest": getDigest("CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N")};
256+
}
257+
258+
let cvss_9_score_6 = () => {
259+
return {"digest": getDigest("CVSS:4.0/AV:L/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N")};
260+
}
261+
230262
const DEFS = {
231263
"crypto_caesar": caesarEnc,
232264
"crypto_vigenere": vigenereEnc,
@@ -235,12 +267,20 @@ const DEFS = {
235267
"crypto_hash": hashEnc,
236268
"crypto_xor": xorEnc,
237269
"crypto_pbk": pbkEnc,
238-
"crypto_analysis": analysisEnc
270+
"crypto_analysis": analysisEnc,
271+
"cvss_3_score_1": cvss_3_score_1,
272+
"cvss_4_score_2": cvss_4_score_2,
273+
"cvss_5_chain": cvss_5_chain,
274+
"cvss_6_score_3": cvss_6_score_3,
275+
"cvss_7_score_4": cvss_7_score_4,
276+
"cvss_8_score_5": cvss_8_score_5,
277+
"cvss_9_score_6": cvss_9_score_6
239278
}
240279

241280
module.exports = {
242281
DEFS,
243282
getCode,
283+
getDigest,
244284
checkCode,
245285
xorOp
246286
}

trainingportal/static/challenges.html

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,24 +74,38 @@ <h4>Challenge</h4>
7474
The play link has been provided to you when solving the previous module or challenge.
7575
If you have missed it read the challenge description carefully and try to figure out what it is.
7676
</p>
77-
<div ng-if="challenge.question" class="alert alert-info" style="color: black;">
77+
<div ng-if="challenge.question.code" class="alert alert-info" style="color: black;">
7878
<textarea rows="10" readonly style="background-color: transparent; border: 0px; width: 100%">{{challenge.question.code}}</textarea>
7979
</div>
8080

81+
<span ng-if="challenge.options">
82+
<div class="form-check" ng-repeat="op in challenge.options">
83+
<input class="form-check-input option-{{challenge.id}}" type="radio" value="{{op.value}}" name="option" id="option-{{challenge.id}}-{{$index}}">
84+
<label class="form-check-label" for="option-{{challenge.id}}-{{$index}}">
85+
{{op.display}}
86+
</label>
87+
</div>
88+
</span>
89+
8190
<span ng-if="!challenge.passed">
8291

92+
<span ng-if="challenge.options">
93+
<br>
94+
<a ng-click="submitOption(challenge.id, challenge.question.digest)" class="btn btn-info btn-sm" role="button">Submit Answer</a>
95+
</span>
96+
8397
<span ng-if="challenge.type !== 'quiz'">
8498
<p>
8599
Once you were able to complete the challenge you can generate a code which you can submit below.
86100
</p>
87101
<a ng-href="#!submitCode/{{moduleId}}/{{challenge.id}}/page/0" class="btn btn-info btn-sm" role="button">Submit Code</a>
88102
</span>
89103

90-
<span ng-if="challenge.type === 'quiz'">
91-
<p>
92-
Once you were able to find the answer you can submit it below.
93-
</p>
94-
<a ng-href="#!submitCode/{{moduleId}}/{{challenge.id}}/quiz/{{challenge.question.digest}}" class="btn btn-info btn-sm" role="button">Submit Answer</a>
104+
<span ng-if="challenge.type === 'quiz' && !challenge.options">
105+
<label for="answer-{{challenge.id}}">Answer:</label> &nbsp;
106+
<input type="text" autocomplete="off" class="form-control" style="width: 100%;" id="answer-{{challenge.id}}" value=""/>
107+
<br>
108+
<a ng-click="submitAnswer(challenge.id, challenge.question.digest)" class="btn btn-info btn-sm" role="button">Submit Answer</a>
95109
</span>
96110

97111
</span>

trainingportal/static/challengesCtrl.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,36 @@ app.controller("challengesCtrl", function($scope, $http, $routeParams) {
2424

2525
}
2626

27+
$scope.submitOption = function(id, digest){
28+
let answer = null;
29+
let options = document.getElementsByClassName(`option-${id}`);
30+
for(let op of options){
31+
if(op.checked){
32+
answer = op.value
33+
break;
34+
}
35+
}
36+
$scope.saveAnswer(answer,id,digest);
37+
}
38+
39+
$scope.submitAnswer = function(id, digest){
40+
let answer = null;
41+
let el = document.getElementById(`answer-${id}`);
42+
if(el){
43+
answer = el.value;
44+
}
45+
$scope.saveAnswer(answer,id,digest);
46+
}
47+
48+
$scope.saveAnswer = function(answer, id, digest){
49+
if(answer !== null){
50+
localStorage.setItem("dojo.current.answer", answer);
51+
localStorage.setItem("dojo.current.challenge", window.location.href);
52+
window.location.href = `#!submitCode/${$scope.moduleId}/${id}/quiz/${digest}`;
53+
}
54+
}
55+
56+
2757
$scope.loadChallenges = function(){
2858
$http.get(`/challenges/${$scope.moduleId}`)
2959
.then(function(response) {

0 commit comments

Comments
 (0)