start of missing function ac lesson

This commit is contained in:
Jason White 2017-07-24 16:26:23 -04:00
parent ca4b0c06b5
commit c44186f986
23 changed files with 444 additions and 1 deletions

View File

@ -260,6 +260,8 @@ public class CreateDB {
String insertData11 = "INSERT INTO user_data VALUES (15603,'Peter','Sand','123609789','MC',' ',0)";
String insertData12 = "INSERT INTO user_data VALUES (15603,'Peter','Sand','338893453333','AMEX',' ',0)";
String insertData13 = "INSERT INTO user_data VALUES (15613,'Joesph','Something','33843453533','AMEX',' ',0)";
String insertData14 = "INSERT INTO user_data VALUES (15837,'Chaos','Monkey','32849386533','CM',' ',0)";
String insertData15 = "INSERT INTO user_data VALUES (19204,'Mr','Goat','33812953533','VISA',' ',0)";
statement.executeUpdate(insertData1);
statement.executeUpdate(insertData2);
statement.executeUpdate(insertData3);
@ -273,6 +275,8 @@ public class CreateDB {
statement.executeUpdate(insertData11);
statement.executeUpdate(insertData12);
statement.executeUpdate(insertData13);
statement.executeUpdate(insertData14);
statement.executeUpdate(insertData15);
}

Binary file not shown.

View File

@ -0,0 +1,12 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>missing-function-ac</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>org.owasp.webgoat.lesson</groupId>
<artifactId>webgoat-lessons-parent</artifactId>
<version>8.0-SNAPSHOT</version>
</parent>
</project>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,61 @@
package org.owasp.webgoat.plugin;
import com.google.common.collect.Lists;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.session.UserSessionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by jason on 1/5/17.
*/
@AssignmentPath("/access-control/hidden-menu")
@AssignmentHints({"access-control.hidden-menus.hint1","access-control.hidden-menus.hint2","access-control.hidden-menus.hint3"})
public class HiddenMenuItems extends AssignmentEndpoint {
//UserSessionData is bound to session and can be used to persist data across multiple assignments
@Autowired
UserSessionData userSessionData;
@PostMapping(produces = {"application/json"})
public @ResponseBody
AttackResult completed(String hiddenMenu1, String hiddenMenu2, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//overly simple example for success. See other existing lesssons for ways to detect 'success' or 'failure'
if (hiddenMenu1.equals("List Users") && hiddenMenu2.equals("Add User")) {
return trackProgress(success()
.output("")
.feedback("access-control.hidden-menus.success")
.build());
}
if (hiddenMenu1.equals("Add User") && hiddenMenu2.equals("List Users")) {
return trackProgress(success()
.output("")
.feedback("access-control.hidden-menus.close")
.build());
}
return trackProgress(failed()
.feedback("access-control.hidden-menus.failure")
.output("")
.build());
}
}

View File

@ -0,0 +1,54 @@
package org.owasp.webgoat.plugin;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.session.UserSessionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
/**
* Created by jason on 1/5/17.
*/
@AssignmentPath("/access-control/list-users")
@AssignmentHints({"access-control.hidden-menus.hint1","access-control.hidden-menus.hint2","access-control.hidden-menus.hint3"})
public class MissingACListUsers extends AssignmentEndpoint {
//UserSessionData is bound to session and can be used to persist data across multiple assignments
@Autowired
UserSessionData userSessionData;
@PostMapping(produces = {"application/json"})
public @ResponseBody
AttackResult completed(String hiddenMenu1, String hiddenMenu2, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//overly simple example for success. See other existing lesssons for ways to detect 'success' or 'failure'
if (hiddenMenu1.equals("List Users") && hiddenMenu2.equals("Add User")) {
return trackProgress(success()
.output("")
.feedback("access-control.hidden-menus.success")
.build());
}
if (hiddenMenu1.equals("Add User") && hiddenMenu2.equals("List Users")) {
return trackProgress(success()
.output("")
.feedback("access-control.hidden-menus.close")
.build());
}
return trackProgress(failed()
.feedback("access-control.hidden-menus.failure")
.output("")
.build());
}
}

View File

@ -0,0 +1,62 @@
package org.owasp.webgoat.plugin;
import com.beust.jcommander.internal.Lists;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.NewLesson;
import java.util.List;
/**
* ************************************************************************************************
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
* <p>
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* <p>
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*
*/
public class MissingFunctionAC extends NewLesson {
@Override
public Category getDefaultCategory() {
return Category.ACCESS_CONTROL;
}
@Override
public List<String> getHints() {
return Lists.newArrayList();
}
@Override
public Integer getDefaultRanking() {
return 40;
}
@Override
public String getTitle() {
return "missing-function-access-control.title";
}
@Override
public String getId() {
return "MissingFunctionAC";
}
}

View File

@ -0,0 +1,113 @@
package org.owasp.webgoat.plugin;
import com.sun.org.apache.xpath.internal.axes.HasPositionalPredChecker;
import org.owasp.webgoat.assignments.Endpoint;
import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.UserSessionData;
import org.owasp.webgoat.session.WebSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import static javax.swing.UIManager.getString;
public class Users extends Endpoint{
@Autowired
private WebSession webSession;
@Autowired
UserSessionData userSessionData;
@RequestMapping(produces = {"application/json"}, method = RequestMethod.GET)
@ResponseBody
protected HashMap<Integer, HashMap> getUsers (HttpServletRequest req) {
try {
Connection connection = DatabaseUtilities.getConnection(getWebSession());
String query = "SELECT * FROM user_data";
try {
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery(query);
HashMap<Integer,HashMap> allUsersMap = new HashMap();
if ((results != null) && (results.first() == true)) {
ResultSetMetaData resultsMetaData = results.getMetaData();
StringBuffer output = new StringBuffer();
while (results.next()) {
int id = results.getInt(0);
HashMap<String,String> userMap = new HashMap<>();
userMap.put("first", results.getString(1));
userMap.put("last", results.getString(2));
userMap.put("cc", results.getString(3));
userMap.put("ccType", results.getString(4));
userMap.put("cookie", results.getString(5));
userMap.put("loginCOunt",Integer.toString(results.getInt(6)));
allUsersMap.put(id,userMap);
}
userSessionData.setValue("allUsers",allUsersMap);
return allUsersMap;
}
} catch (SQLException sqle) {
sqle.printStackTrace();
HashMap<String,String> errMap = new HashMap() {{
put("err",sqle.getErrorCode() + "::" + sqle.getMessage());
}};
return new HashMap<Integer,HashMap>() {{
put(0,errMap);
}};
} catch (Exception e) {
e.printStackTrace();
HashMap<String,String> errMap = new HashMap() {{
put("err",e.getMessage() + "::" + e.getCause());
}};
e.printStackTrace();
return new HashMap<Integer,HashMap>() {{
put(0,errMap);
}};
} finally {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException sqle) {
sqle.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
HashMap<String,String> errMap = new HashMap() {{
put("err",e.getMessage() + "::" + e.getCause());
}};
e.printStackTrace();
return new HashMap<Integer,HashMap>() {{
put(0,errMap);
}};
}
return null;
}
protected WebSession getWebSession() {
return webSession;
}
@Override
public String getPath() {
return "/access-control/list-users";
}
}

Binary file not shown.

View File

@ -0,0 +1,81 @@
<html xmlns:th="http://www.thymeleaf.org">
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:missing-function-ac-01-intro.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:missing-function-ac-02-client-controls.adoc"></div>
<script th:src="@{/lesson_js/missing-function-ac.js}" > </script>
<div class="attack-container">
<div id="ac-menu-wrapper">
<div id="ac-menu">
<h3 class="menu-header">Account</h3>
<div class="menu-section">
<ul>
<li>My Profile</li>
<li>Privacy/Security</li>
<li>Log Out</li>
</ul>
</div>
<h3 class="menu-header">Messages</h3>
<div class="menu-section">
<ul>
<li>Unread Messages (3)</li>
<li>Compose Message</li>
</ul>
</div>
<h3 class="hidden-menu-item menu-header">Admin</h3>
<div class="menu-section hidden-menu-item">
<ul>
<li>List Users</li>
<li>Add User</li>
</ul>
</div>
</div>
</div>
<br/>
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/access-control/hidden-menu">
<p>Hidden Item 1 <input name="hiddenMenu1" value="" type="TEXT" /></p>
<p>Hidden Item 2 <input name="hiddenMenu2" value="" type="TEXT" /></p>
<br/>
<input name="submit" value="Submit" type="SUBMIT"/>
</form>
<div class="attack-feedback"></div>
<div class="attack-output"></div>
</div>
</div>
<!--<div class="lesson-page-wrapper">-->
<!--<div class="adoc-content" th:replace="doc:missing-function-ac-03-list-users.adoc"></div>-->
<!--<div class="attack-container">-->
<!--<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>-->
<!--<form class="attack-form" accept-charset="UNKNOWN"-->
<!--method="POST" name="form"-->
<!--action="/WebGoat/access-control/user-info">-->
<!--<p>CC Number: <input name="ccNum" value="" type="TEXT" /></p>-->
<!--<br/>-->
<!--<input name="submit" value="Submit" type="SUBMIT"/>-->
<!--</form>-->
<!--<div class="attack-feedback"></div>-->
<!--<div class="attack-output"></div>-->
<!--</div>-->
<!--</div>-->
</html>

View File

@ -0,0 +1,9 @@
missing-function-access-control.title=Missing Function Level Access Control
access-control.hidden-menus.success=Correct! And not hard to find are they?!? For the next lab, note that the endpoints are at /WebGoat/access-control/list-users and /WebGoat/access-control/add-user
access-control.hidden-menus.close=Close. Remember that when hacking ... details such as order,case and the like matter.
access-control.hidden-menus.failure=Please try again.
access-control.hidden-menus.hint1=You can inspect the DOM or review the source in the proxy request/response cycle.
access-control.hidden-menus.hint2=Look for indications of something that would not be available to a typical user
access-control.hidden-menus.hint3=Look for something a super-user or administator might have available to them

View File

@ -0,0 +1,6 @@
webgoat.customjs.accessControlMenu = function() {
//webgoat.customjs.jquery('#ac-menu-ul').menu();
webgoat.customjs.jquery('#ac-menu').accordion();
}
webgoat.customjs.accessControlMenu();

View File

@ -0,0 +1,9 @@
== Missing Function Level Access Control
Access control, like output encoding XSS can be tricky to maintain and ensure it is enforced properly throughout an application, including at each method/function.
=== IDOR vs Missing Function Level Access Control
The fact is many people (including the author of this lesson) would lump function level access control and IDOR into 'Access Control'. For sake of OWASP, Top 10 and these lessons, we will make a
distinction. The distinction most make is that IDOR is more of a 'horizontal' or 'lateral' access control issue, and missing function level access control 'exposes functionality'. Even though,
the IDOR lesson here demonstrates how functionality may also be exposed, (at least to another user in the same role), we will look at other ways functionality might be exposed.

View File

@ -0,0 +1,16 @@
== Relying on Obscurity
If you are relying on HTML, CSS or javascript to hide links that users don't normally access.
It's a little older, but there was a case of a network router trying to protect (hide) admin functions with javascript in the UI https://www.wired.com/2009/10/routers-still-vulnerable
=== Finding Hidden Items
There are usually hints to finding functionality the UI does not openly expose in ...
* HTML or javascript comments
* Commented out elements
* Items hidden via css controls/classes
=== Your Mission
Find two menu items not visible in menu below that are or would be of interest to an attacker/malicious user and put the labels for those menu items (there are no links right now in the menus).

View File

@ -0,0 +1,10 @@
== Just Try It
As the previous page noted, sometimes apps rely on client controls. to control access (obscurity). If you can find items that don't have visible links, just try them, see what happens. Yes, it
can be that simple!
=== Gathering User Info
Often times, data dumps from vulnerabilities such as sql injection, but they can also come from poor or lacking access control. Use the info. you already gathered to pull the list of users and
then provide the CC# for Chaos Monkey.

View File

@ -28,6 +28,7 @@
<module>idor</module>
<module>vulnerable-components</module>
<module>auth-bypass</module>
<module>missing-function-ac</module>
<!-- uncomment below to include lesson template in build, also uncomment the dependency in webgoat-server/pom.xml to have it run in the project fully -->
<!--<module>webgoat-lesson-template</module>-->
</modules>

View File

@ -154,6 +154,11 @@
<artifactId>auth-bypass</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.owasp.webgoat.lesson</groupId>
<artifactId>missing-function-ac</artifactId>
<version>${project.version}</version>
</dependency>
<!--uncommment below to run/include lesson template in WebGoat Build-->
<!--<dependency>-->