Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding challenge for CWE-94 #143

Merged
merged 4 commits into from
Mar 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified AttackGrams.pptx
Binary file not shown.
6 changes: 5 additions & 1 deletion insecureinc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@
<artifactId>tomcat-util</artifactId>
<version>8.5.53</version>
</dependency>

<dependency>
<groupId>org.openjdk.nashorn</groupId>
<artifactId>nashorn-core</artifactId>
<version>15.4</version>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
64 changes: 64 additions & 0 deletions insecureinc/src/main/java/insecure/inc/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

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

}


public static String executeJavascript(String command) {
if (command == null) {
command = "";
}

String PASSWORD = "Sup3rS3cr3t";

// permit simple arithmetic expressions
Pattern calculatorPattern = Pattern.compile("^[0-9+\\-*\\/]*$");
Matcher calculatorPatternMatcher = calculatorPattern.matcher(command);

// permit "password"
Pattern passwordPattern = Pattern.compile("^password$");
Matcher passwordPatternMatcher = passwordPattern.matcher(command);

// permit a call to the function deleteHistory, providing the correct password
Pattern exploitPattern = Pattern.compile("^deleteHistory\\(['\\\"`]{1}Sup3rS3cr3t['\\\"`]{1}\\);*$");
Matcher exploitPatternMatcher = exploitPattern.matcher(command);

// permit a call to the function deleteHistory, providing the incorrect password
Pattern exploitPatternWrongPassword = Pattern.compile("^deleteHistory\\(['\\\"`]{1}.*['\\\"`]{1}\\);*$");
Matcher exploitPatternWrongPasswordMatcher = exploitPatternWrongPassword.matcher(command);

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
String result = "";

if (exploitPatternMatcher.find()) {
return "solved";
}

if (exploitPatternWrongPasswordMatcher.find()) {
return command + " = wrong password";
}

// Only allow a limited possibility for executable code to pass through, so as to protect the SecureCodingDojo instance
if (calculatorPatternMatcher.find() || passwordPatternMatcher.find()) {
try {
// Don't display this in code snippet - they are just dummy functions that ensure the JavaScript code all loads
engine.eval("function authenticate(password) { return false; }");
engine.eval("function clearDatabase() { return false; }");

// Do display this in code snippet - it will help to understand how to exploit this challenge
engine.eval("var password = '" + PASSWORD + "';");
engine.eval("function deleteHistory(password) { if (authenticate(password)) { clearDatabase(); } else { return 'wrong password'; } }");
Object outcome = engine.eval(command);

if (outcome != null) {
result = command + " = " + outcome.toString();
}
} catch (ScriptException e) {
System.err.println(e);
}
}

return result;
}


public static String bytesToHex(byte[] in) {
final StringBuilder builder = new StringBuilder();
for(byte b : in) {
Expand Down
58 changes: 58 additions & 0 deletions insecureinc/src/main/webapp/cwe94.jsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="inc.insecure.*" %>
<%@ page import="insecure.inc.Constants" %>
<%@ page import="insecure.inc.Util" %>
<%
String alertVisibility = "hidden";
String query = request.getParameter("query");

if (query != null) {
query = query.trim();
alertVisibility = "";
}

String result = Util.executeJavascript(query);

if (result == "solved") {
session.setAttribute(Constants.CHALLENGE_ID,"cwe94");
response.sendRedirect(Constants.SECRET_PAGE);
}
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Improper Control of Generation of Code ('Code Injection')</title>
<link rel="stylesheet" href="public/bootstrap/css/bootstrap.min.css">
<script src="public/jquery.min.js"></script>
<script src="public/bootstrap/js/bootstrap.min.js"></script>

</head>
<body>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="index.jsp">Insecure Inc.</a>
</div>
<ul class="nav navbar-nav">
<li class="active"><a href="#">Improper Control of Generation of Code ('Code Injection')</a></li>
</ul>
</div>
</nav>
<div class="container">
<h1>Welcome to CWE94 - Improper Control of Generation of Code ('Code Injection')!</h1>
<p>Please enter your mathematical operation and the backend JavaScript engine will provide the result.</p>
<form action="cwe94.jsp" autocomplete="off" method="POST">
<div class="form-group">
<label for="expression">Mathematical Expression:</label>
<input type="text" class="form-control" id="expression" name="query">
</div>
<input type="submit" id="submit" class="btn" value="Submit">
<br><br>
<div class="alert alert-danger <%=alertVisibility%>">
Result: <%=result%>
</div>
</form>
</div>
</body>
</html>
3 changes: 2 additions & 1 deletion insecureinc/src/main/webapp/index.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ body {
<li><a href="cwe327.jsp">Use of a Broken or Risky Cryptographic Algorithm</a></li>
<li><a href="cwe759.jsp">Use of a One-Way Hash without a Salt</a></li>
<li><a href="cwe798.jsp">Use of Hard-coded Credentials</a></li>
<li><a href="cwe209.jsp">Generation of Error Message Containing Sensitive Information</a></li>
<li><a href="cwe209.jsp">Generation of Error Message Containing Sensitive Information</a></li>
<li><a href="cwe94.jsp">Improper Control of Generation of Code ('Code Injection')</a></li>
<li><a href="cwe307.jsp">Improper Restriction of Excessive Authentication Attempts</a></li>
<li><a href="cwe190.jsp">Integer Overflow or Wraparound</a></li>
<li><a href="cwe494.jsp">Download of Code Without Integrity Check</a></li>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions trainingportal/static/lessons/blackBelt/cwe94.html
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also use MD files for challenge descriptions. Check out the Red Team/Blue Team modules.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<p>
The purpose of this challenge is to demonstrate the MITRE Top 25 programming flaw: 'Improper Control of Generation of Code ('Code Injection')'.
<br><br>

<blockquote>
<p>
<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>
</p>
<footer>From MITRE <a target="_blank" rel="noopener noreferrer" href="https://cwe.mitre.org/data/definitions/94.html">CWE 94</a></footer>
</blockquote>
<p>
The developer of this part of the site has implemented a server side calculator that expects a mathematical expression from the user to calculate.
The issue is that the server side code runs the user input through eval(), which means that any input is treated as executable code.
</p>
<p>
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.
</p>
<p>
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.
</p>
<pre class="pre-scrollable">
public static String calculate(String mathematicalExpression) {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
String result = "";

engine.eval("var password = '" + PASSWORD + "';");
engine.eval("function deleteHistory(password) { if (authenticate(password)) { clearDatabase(); } else { return 'wrong password'; } }");
Object outcome = engine.eval(mathematicalExpression);

if (outcome != null) {
result = command + " = " + outcome.toString();
}

return result;
}
</pre>
11 changes: 11 additions & 0 deletions trainingportal/static/lessons/blackBelt/cwe94.sol.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
### Solution for "Improper Control of Generation of Code ('Code Injection')" challenge

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.
External input should never be trusted as it may actually be executable code.
Always apply server side input validation to external input to help protect against code injection.

To pass this challenge:

- Become familiar with the Insecure Inc. Calculator and study the code snippet in the challenge description.
- Obtain the value for the password that is loaded into the runtime environment.
- Invoke the `deleteHistory` utility, providing the correct password.
10 changes: 10 additions & 0 deletions trainingportal/static/lessons/blackBelt/definitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,16 @@
"solution":"cwe494.sol.md",
"playLink":"/cwe494.jsp",
"codeBlockIds":["integrityVerification","useStrongDataEncryption"]
},
{
"id":"cwe94",
"name":"Improper Control of Generation of Code ('Code Injection')",
"description": "cwe94.html",
"attackGram":"codeinjection.png",
"solution":"cwe94.sol.md",
"playLink":"/cwe94.jsp",
"mission":"Invoke the server side utility `deleteHistory`.",
"codeBlockIds":["inputAllowListing", "serverSideValidation"]
}
]
},
Expand Down
2 changes: 1 addition & 1 deletion trainingportal/static/lessons/modules.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"name":"Black Belt",
"summary":"Common software security flaws",
"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.",
"description2":"Includes 24 lessons. Estimated duration 4 hours.",
"description2":"Includes 25 lessons. Estimated duration 4 hours.",
"badgeInfo":{
"line1":"Secure Coding",
"line2":"Black Belt",
Expand Down
Loading