Skip to content

Commit ae1d553

Browse files
authored
Merge pull request #143 from timmyteo/feature/cwe-94
Adding challenge for CWE-94
2 parents d87f069 + 1fab212 commit ae1d553

File tree

10 files changed

+188
-3
lines changed

10 files changed

+188
-3
lines changed

AttackGrams.pptx

2.04 KB
Binary file not shown.

insecureinc/pom.xml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@
2929
<artifactId>tomcat-util</artifactId>
3030
<version>8.5.53</version>
3131
</dependency>
32-
32+
<dependency>
33+
<groupId>org.openjdk.nashorn</groupId>
34+
<artifactId>nashorn-core</artifactId>
35+
<version>15.4</version>
36+
</dependency>
3337
</dependencies>
3438
<build>
3539
<plugins>

insecureinc/src/main/java/insecure/inc/Util.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@
3131
import javax.xml.transform.dom.DOMSource;
3232
import javax.xml.transform.stream.StreamResult;
3333

34+
import javax.script.ScriptEngine;
35+
import javax.script.ScriptEngineManager;
36+
import javax.script.ScriptException;
37+
3438
import org.w3c.dom.Document;
3539
import org.xml.sax.SAXException;
3640

@@ -81,7 +85,67 @@ public static String exec(String ... commandArgs) throws IOException, Interrupte
8185
return sb.toString();
8286

8387
}
88+
89+
90+
public static String executeJavascript(String command) {
91+
if (command == null) {
92+
command = "";
93+
}
94+
95+
String PASSWORD = "Sup3rS3cr3t";
96+
97+
// permit simple arithmetic expressions
98+
Pattern calculatorPattern = Pattern.compile("^[0-9+\\-*\\/]*$");
99+
Matcher calculatorPatternMatcher = calculatorPattern.matcher(command);
100+
101+
// permit "password"
102+
Pattern passwordPattern = Pattern.compile("^password$");
103+
Matcher passwordPatternMatcher = passwordPattern.matcher(command);
104+
105+
// permit a call to the function deleteHistory, providing the correct password
106+
Pattern exploitPattern = Pattern.compile("^deleteHistory\\(['\\\"`]{1}Sup3rS3cr3t['\\\"`]{1}\\);*$");
107+
Matcher exploitPatternMatcher = exploitPattern.matcher(command);
108+
109+
// permit a call to the function deleteHistory, providing the incorrect password
110+
Pattern exploitPatternWrongPassword = Pattern.compile("^deleteHistory\\(['\\\"`]{1}.*['\\\"`]{1}\\);*$");
111+
Matcher exploitPatternWrongPasswordMatcher = exploitPatternWrongPassword.matcher(command);
112+
113+
ScriptEngineManager manager = new ScriptEngineManager();
114+
ScriptEngine engine = manager.getEngineByName("JavaScript");
115+
String result = "";
116+
117+
if (exploitPatternMatcher.find()) {
118+
return "solved";
119+
}
120+
121+
if (exploitPatternWrongPasswordMatcher.find()) {
122+
return command + " = wrong password";
123+
}
124+
125+
// Only allow a limited possibility for executable code to pass through, so as to protect the SecureCodingDojo instance
126+
if (calculatorPatternMatcher.find() || passwordPatternMatcher.find()) {
127+
try {
128+
// Don't display this in code snippet - they are just dummy functions that ensure the JavaScript code all loads
129+
engine.eval("function authenticate(password) { return false; }");
130+
engine.eval("function clearDatabase() { return false; }");
131+
132+
// Do display this in code snippet - it will help to understand how to exploit this challenge
133+
engine.eval("var password = '" + PASSWORD + "';");
134+
engine.eval("function deleteHistory(password) { if (authenticate(password)) { clearDatabase(); } else { return 'wrong password'; } }");
135+
Object outcome = engine.eval(command);
136+
137+
if (outcome != null) {
138+
result = command + " = " + outcome.toString();
139+
}
140+
} catch (ScriptException e) {
141+
System.err.println(e);
142+
}
143+
}
144+
145+
return result;
146+
}
84147

148+
85149
public static String bytesToHex(byte[] in) {
86150
final StringBuilder builder = new StringBuilder();
87151
for(byte b : in) {
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
2+
<%@ page import="inc.insecure.*" %>
3+
<%@ page import="insecure.inc.Constants" %>
4+
<%@ page import="insecure.inc.Util" %>
5+
<%
6+
String alertVisibility = "hidden";
7+
String query = request.getParameter("query");
8+
9+
if (query != null) {
10+
query = query.trim();
11+
alertVisibility = "";
12+
}
13+
14+
String result = Util.executeJavascript(query);
15+
16+
if (result == "solved") {
17+
session.setAttribute(Constants.CHALLENGE_ID,"cwe94");
18+
response.sendRedirect(Constants.SECRET_PAGE);
19+
}
20+
%>
21+
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
22+
<html>
23+
<head>
24+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
25+
<title>Improper Control of Generation of Code ('Code Injection')</title>
26+
<link rel="stylesheet" href="public/bootstrap/css/bootstrap.min.css">
27+
<script src="public/jquery.min.js"></script>
28+
<script src="public/bootstrap/js/bootstrap.min.js"></script>
29+
30+
</head>
31+
<body>
32+
<nav class="navbar navbar-inverse">
33+
<div class="container-fluid">
34+
<div class="navbar-header">
35+
<a class="navbar-brand" href="index.jsp">Insecure Inc.</a>
36+
</div>
37+
<ul class="nav navbar-nav">
38+
<li class="active"><a href="#">Improper Control of Generation of Code ('Code Injection')</a></li>
39+
</ul>
40+
</div>
41+
</nav>
42+
<div class="container">
43+
<h1>Welcome to CWE94 - Improper Control of Generation of Code ('Code Injection')!</h1>
44+
<p>Please enter your mathematical operation and the backend JavaScript engine will provide the result.</p>
45+
<form action="cwe94.jsp" autocomplete="off" method="POST">
46+
<div class="form-group">
47+
<label for="expression">Mathematical Expression:</label>
48+
<input type="text" class="form-control" id="expression" name="query">
49+
</div>
50+
<input type="submit" id="submit" class="btn" value="Submit">
51+
<br><br>
52+
<div class="alert alert-danger <%=alertVisibility%>">
53+
Result: <%=result%>
54+
</div>
55+
</form>
56+
</div>
57+
</body>
58+
</html>

insecureinc/src/main/webapp/index.jsp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ body {
6464
<li><a href="cwe327.jsp">Use of a Broken or Risky Cryptographic Algorithm</a></li>
6565
<li><a href="cwe759.jsp">Use of a One-Way Hash without a Salt</a></li>
6666
<li><a href="cwe798.jsp">Use of Hard-coded Credentials</a></li>
67-
<li><a href="cwe209.jsp">Generation of Error Message Containing Sensitive Information</a></li>
67+
<li><a href="cwe209.jsp">Generation of Error Message Containing Sensitive Information</a></li>
68+
<li><a href="cwe94.jsp">Improper Control of Generation of Code ('Code Injection')</a></li>
6869
<li><a href="cwe307.jsp">Improper Restriction of Excessive Authentication Attempts</a></li>
6970
<li><a href="cwe190.jsp">Integer Overflow or Wraparound</a></li>
7071
<li><a href="cwe494.jsp">Download of Code Without Integrity Check</a></li>
25.9 KB
Loading
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<p>
2+
The purpose of this challenge is to demonstrate the MITRE Top 25 programming flaw: 'Improper Control of Generation of Code ('Code Injection')'.
3+
<br><br>
4+
5+
<blockquote>
6+
<p>
7+
<i>The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.</i>
8+
</p>
9+
<footer>From MITRE <a target="_blank" rel="noopener noreferrer" href="https://cwe.mitre.org/data/definitions/94.html">CWE 94</a></footer>
10+
</blockquote>
11+
<p>
12+
The developer of this part of the site has implemented a server side calculator that expects a mathematical expression from the user to calculate.
13+
The issue is that the server side code runs the user input through eval(), which means that any input is treated as executable code.
14+
</p>
15+
<p>
16+
Below is a portion of the application code. You will see the developers are also loading some other unrelated backend utility code into the runtime environment. See if you can determine a way to exploit this.
17+
</p>
18+
<p>
19+
Your task is to invoke the existing `deleteHistory` utility loaded into the runtime environment, likely causing issues to data stored somewhere on the server side.
20+
</p>
21+
<pre class="pre-scrollable">
22+
public static String calculate(String mathematicalExpression) {
23+
ScriptEngineManager manager = new ScriptEngineManager();
24+
ScriptEngine engine = manager.getEngineByName("JavaScript");
25+
String result = "";
26+
27+
engine.eval("var password = '" + PASSWORD + "';");
28+
engine.eval("function deleteHistory(password) { if (authenticate(password)) { clearDatabase(); } else { return 'wrong password'; } }");
29+
Object outcome = engine.eval(mathematicalExpression);
30+
31+
if (outcome != null) {
32+
result = command + " = " + outcome.toString();
33+
}
34+
35+
return result;
36+
}
37+
</pre>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
### Solution for "Improper Control of Generation of Code ('Code Injection')" challenge
2+
3+
When a system inserts external input into an engine that is capable of executing code, the input can exploit this fact by executing code that will accomplish some goal unintended by the system creator.
4+
External input should never be trusted as it may actually be executable code.
5+
Always apply server side input validation to external input to help protect against code injection.
6+
7+
To pass this challenge:
8+
9+
- Become familiar with the Insecure Inc. Calculator and study the code snippet in the challenge description.
10+
- Obtain the value for the password that is loaded into the runtime environment.
11+
- Invoke the `deleteHistory` utility, providing the correct password.

trainingportal/static/lessons/blackBelt/definitions.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,16 @@
142142
"solution":"cwe494.sol.md",
143143
"playLink":"/cwe494.jsp",
144144
"codeBlockIds":["integrityVerification","useStrongDataEncryption"]
145+
},
146+
{
147+
"id":"cwe94",
148+
"name":"Improper Control of Generation of Code ('Code Injection')",
149+
"description": "cwe94.html",
150+
"attackGram":"codeinjection.png",
151+
"solution":"cwe94.sol.md",
152+
"playLink":"/cwe94.jsp",
153+
"mission":"Invoke the server side utility `deleteHistory`.",
154+
"codeBlockIds":["inputAllowListing", "serverSideValidation"]
145155
}
146156
]
147157
},

trainingportal/static/lessons/modules.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"name":"Black Belt",
1818
"summary":"Common software security flaws",
1919
"description":"This module is based on the SANS Top 25 - Most Dangerous Software Flaws. Lessons are entry level difficulty aimed at introducing the concepts of vulnerability, exploit and software defense.",
20-
"description2":"Includes 24 lessons. Estimated duration 4 hours.",
20+
"description2":"Includes 25 lessons. Estimated duration 4 hours.",
2121
"badgeInfo":{
2222
"line1":"Secure Coding",
2323
"line2":"Black Belt",

0 commit comments

Comments
 (0)