20165207 Exp9 Web安全基础

20165207 Exp9 Web安全基础

一、实验过程

1、环境配置

本次实验要安装由OWASP开发出来的web实验平台Webgoat,实验指导里提供的webgoat版本是7.0.1版本的,根据官方解释jdk版本大于等于1.6即可正常运行那个jar包,然而并非如此。我在输入了正常的命令之后使用默认用户guest登录,登录后重定向的界面的左侧并没有预期的课程列表。经过我的队友张家佳同学的提示,我才知道我们kali里面的openjdk11运行Webgoat7.0.1版本的jar包就是会出现这样的结果。如果还是想使用这个版本的webgoat包就需要将原有的jdk卸载然后装上jdk1.7或者jdk1.8或者干脆换一个jdk版本是1.8版本的kali虚拟机。
可是……我并没有这么做,因为我的学习盘快满了并且换jdk有可能把kali搞坏,好吧……其实我就是想试一下大家都没用过的新版Webgoat8.0.0.M25,进入到github上webgoat项目的releases下找到8.0.0.M25的下载链接。

下载下来安装包之后,使用共享文件夹拷到虚拟机里,并参考下图输入安装命令

在出现这一行(start)之后终端发生了阻塞,应该是开启成功了

然后在浏览器中输入网址localhost:8080/WebGoat,会出现用户登录界面,然而没有告诉你默认的用户名和密码,需要自己注册。祖册完成之后登进去是这样的:

2、代理工具burpsuite

我这个版本的webgoat有一节讲http proxies的课,不过这里讲的是工具ZAP,而且它说如果用burp用的惯就可以跳过这步。
我也查了一下,貌似burp更高级一些

那就用burpsuite吧,

打开,创建一个临时项目,一路确定到达主界面,通过option新建一个代理

特别需要注意的是,配置监听器的时候下面的四大标签里面的option的选择要非常注意,否则有可能拦截不到
我就是都给选上了,也没看意思,第一次试的时候就什么都没拦截下来
开启拦截之后,在浏览器上配置一下代理,在菜单的preferences中的general一栏的最下面

然后就能拦截到了

2.1 Http proxies -> Use the intercept

这节课就是让我用代理工具拦截然后修改数据包嘛

那按着那三个条件改就好了,不过要先在option里把规则设置成只拦截post包和get包否则大海捞针会很痛苦

然后点击submit,这个post包就被拦截到了

按照要求修改

但是这样不能成功,因为数据包的格式不是这样的,如果我要改成GET方法,那那个changeMe=必然不能在下面的数据包里,要放在上面的url里,所以我又试了一下这样修改:

要注意的除了GET的数据包格式,还有就是要求里面要添加的数据包头,一定不能添加在末尾的Connection:close()后面,那样就无效了
哇哦,成功了

3、sql注入学习

选择injection flaws下的这个SQL injection(introduction)这一节,先学习一下入门级的SQL注入。如下图所示,这个introduction级别的SQL注入练习总共有13个环节组成,而前八个环节基本都是SQL语句的教学,像这种

像这样真正的SQL注入是从第九节开始的。那么就先从这个第九节开始吧!

3.1、SQL injection(introduction) -> String SQL injection


好的看来我需要在这几个下拉框里面进行一套选择构造出来一个满足出题者心意的SQL注入语句,经过分析选项,我选出了如下的组合

因为or前面要有一个闭合的单引号组合并且smith这个东西不应该是一个变量把孤立在单引号外的Smith写到SQL语句里只会出错,所以第一个我只选了那个单引号,后面两个选项显而易见,唯一的一个问题是末尾还会有一个自动拼接的单引号没有给我们显示出来,这个结果需要测试一下。这样我们就知道了这个后台拼接出来的SQL语句的全部结构了,然后做出上面那个图片里面的选择就变得非常简单(前提是你得错一下才能知道后面还会再拼接上一个单引号,否则最后一个下拉框的选择就会十分困惑)。
嗯,就是这里的单引号

然后就成功了
上面的那个数字9的小红方块也会变成绿色。

3.2、SQL injection(introduction) -> Numeric SQL injection

这是第10题

根据这句提示我们知道了这两个文本框里面应该只有一个文本框是有sql注入点,或者说是容易被SQL注入的地方只在其中一个文本框里面。
那么,我就开始了尝试。先随便输入两个1,看一下会给我回显什么,看来是这样啊,两个字段都是数字类型的。那应该再试一试究竟是哪个数字有注入点。

在第一个文本框里疯狂试探了几下:

mysql的#注释符被过滤掉了,下面抛出的异常说这不是一个数字,是啊#哪是数字,可是……它居然,发现了。看来这过滤的有点严格。
然后使用两个减号注释呢?当然也是不行的。
在这个文本框里or上一个1=1呢?估计也不行,试了一下,果然不行
所以我果断转向了下一个文本框,or了一下1=1,瞬间成功。

3.3、SQL injection(introduction) -> Compromising confidentiality with String SQL injection

学这个之前,我先把前面教SQL的哪几节课刷绿了,复习一下SQL,感觉这个要动真格的了

根据这节课的描述,这节课是想让我学习一下通过字符串SQL注入获取数据库中的敏感信息从而破坏一个数据库CIA三种特性中的Confidential的特性,也就是机密性。然后根据题干里面说的,我是一个叫约翰·史密斯的人,我在公司里有一个认证令牌,其他员工也有。然后,每天都只能从系统里面看我自己的工资让我感觉很不好,我要通过SQL语句把系统干掉从而获得其他同事的薪水信息。并且我已经知道后台做查询的时候动态构造的SQL语句的结构了,就是这样子的:

所以我应该怎么办呢?没什么好说的了,or一个永真式,然后把后面的东西都注释掉就好了。唯一需要试的就是,这个数据库支持的注释符号是哪种,是#还是--还是/*。经过一番尝试,注释原来是--。嗯,就这样

3.4、SQL injection(introduction) -> Compromising Integrity with Query chaining

这一节是要让我用SQL语句(查询链?)破坏掉数据库的完整性。题干里面有对SQL Query Chain的解释

就是用分号隔开,然后来做多个查询嘛,嗯,学到了。
然后,我继续被带入约翰·史密斯同学的情境里,我发现托比和鲍勃挣的钱比我多,但是我不能坐视不管。所以我要把数据库干掉,让我挣的钱变成最多的。并且,我要牢记我的名字是John Smith认证令牌是SL99A。
我先输一个中规中矩的John Smith和sl99A试一下。

啊哈,原来使用last_name匹配的

系统说我我挣得还是不够,hhhhhh,刚才那节课泄露的信息里挣到最多的人是tobi同学,好像是87000
然后就让我来帮助约翰同学挣到90000块吧,来吧

我是怎么做的呢,其实很容易,第一个text框输Smith第二个text框输SL99A'; UPDATE Employees set SALARY = 90000 where USERID = 37648 --
就是把第一句满足了之后做一个单引号闭合,然后用分号分割出来下一句,下一句利用到了之前泄露出来的userID,还要注意的是根据原来的结构,最后还会有一个单引号,我们要用--把这个单引号注释掉。然后就成功了。

3.5、SQL injection(introduction) -> Compromising Availability

这部分的最后一节了,好激动。

下面题干里给我介绍说,破坏掉一个数据库的可用性,办法有很多。比如删掉账户,改掉人家用户的密码,剥夺人家对数据操纵的权限,或者硬核一点直接把库删了
题的描述是这个样子的

原来约翰同学,心思缜密,想要在acces_log也就是访问记录里面删掉自己干坏事的记录,hhhhhhh
哇哦,原来这个access_log表里可以搜到这么多Smith同学(我)干坏事的记录,啧啧啧

我给他来了一个querychain:Smith' ; delete from access_log where ID BETWEEN 11 AND 14 --
然后他告诉我说,还是有史密斯同学干坏事的记录,建议我删了,好吧

那我来一发,优秀的,不能回滚的,truncate试一下;

这是什么意思,我要给一个架构的名字,可是我不知道啊???
那我直接drop table吧,我又给不出来架构名,我不知道啊
输入,Smith' ; drop table access_log --,成功

3.6 SQL Injection (advanced) -> Pulling data from other tables

我现在进入了进阶版的SQL注入练习,这个单元一共有六节,标红了的题有三节

前两节讲了一些基础知识,大概就是对这个进阶部分一些介绍再加上SQL语句中的特殊字符的讲解
比如用-- # 做单行注释,用/*做多行注释
分号可以连接SQL语句,单引号加号和"||"可以用来连接字符串
char()函数用来构造不带引号的字符串。还有union和join这两个,一个做结果集的集合,另一个根据相同属性列做连接。
然后下面这个题的描述是这个样子的

之前给出了两张表的建表语句,也就是表的结构,我现在要把两张表的数据全部取出,并且获得另一位同学的账户密码

所以说这一关要从Name那里做注入然后会回显出来另一个表里面的密码,在用Dave的名字登录输入Dave的密码。
于是,我在第一个text里面输入这些:Smith' ; select * from user_system_data --(我就是不用你提示的union,hhhhhh)
输出如下图,系统告诉我成功了,问我能不能再用union试一下……

如果要用union就必须保证列数一样,看来用union的时候后面还需要再构造一下
输入:'or 1=1 union select userid, X.user_name,X.password,X.cookie, Y.cc_type,Y.cookie,Y.login_count from user_system_data X, user_data Y --
成功

很容易嘛,我们知道了dave同学的密码了,然后开始在下面的文本框输入
网页的回显是说我成功了,但是上面的红方块并没有变绿,这是为什么呢

不太清楚,但是我成功了呀,它想红就继续红吧

3.7 SQL Injection (advanced)最后一道注入题,以Tom的身份登录

虽然我看了第四节的SQL盲注,第五节这道题我还是研究了一个下午也没有研究出来
hint里面说让我留意服务器的回显,可是在登录页面上只有两种结果,一种是no result match没有匹配的结果,还有一种是说请用用户Tom登录
因为我之前用Tom注册了了一个用户,居然还注册成功了。这边用这个Tom登录,结果服务器告诉我请用Tom登录,真是让人搞不清楚逻辑。
我查到了一个解析,是M21版的webgoat8的进阶注入的最后一题:
WebGoat 8.0 M21失传几关的答案在这里
这篇文章的最下面讲的就是以Tom用户的身份登录,但是他第一步就是获取后台的源代码,也就是进行了更高级的分析,我想跟着做但是并没有没有弄懂是怎么得到后台源代码的。唉

3.8 SQL injection(advanced)最后一题,单选练习题

这是一些关于后台写代码的知识,主要是关于prepare-statement和statement的区别的
之前用jdbc写后台程序的时候,我就知道有这个东西,它比一般的statement执行嵌入式SQL语句会更安全
在这里我就学习到了
prepare-statement的SQL语句可以被DBMS预编译,需要前台传来变量的地方被编译成了问号这种占位符。所以就像最后一道选择题说的如果在注册用户的时候输了一个SQL注入,那这整个东西都会被注入进去,而不是执行你的SQL注入。并且因为预编译机制的存在,这种方法貌似比正常的statement执行查询会更快

答案都在上面了。

4、xss学习

xss分为三种,存储型、反射型和DOM型,可能是因为存储型涉及数据库所以分成了两节课,第一节讲反射型和DOM型,第二节讲存储型,第三节一如既往的是防御

4.1、Cross Site Scripting -> 2.What is XSS?

这节的题很简单因为就是个带用户先体验一下xss的例子。最上面是一发介绍,说xss是一种漏洞,这种漏洞允许用户输入脚本并且浏览器提交的时候不加编码。这种东西是最为流行并且有害的web应用的问题。web应用上有一些“特权功能”是通过JavaScript来连接的,如果这种跳转机制没有被正确地保护起来,用户很容易被人通过xss盗走cookie里面的认证信息。
所以这道入门题就是让我开一个新标签页然后按照他说的在URL里面添加JavaScript脚本,体会一下xss

在新标签页的地址栏输入javascript:alert(document.cookie);网页会给我回显一个会话ID

在旧标签再试一下

两次输出的会话ID是一样的,当然是一样了,这是为我这个用户创建的会话,如果会话不能维持,我岂不是要每开一个标签页就重新登录一次。
回答yes,通过

4.2、Cross Site Scripting -> 7.Reflected XSS

前面stage3到stage6讲了一些相关知识,包括:XSS容易发生在哪里、XSS会导致一些什么结果、xss使钓鱼攻击有效、三种常见的xss攻击
反射型主要的特点就是在服务器响应之后把恶意内容回显给用户,需要社会工程学分析(因为你得知道你想回显的东西的名字)并且它的实现是基于从用户那里继承来的执行脚本的特权。
DOM型和反射型非常类似,也叫技术型反射,主要特点是通过客户端把恶意内容写入http请求,同样需要社工。
存储型或者说持续型,就是把恶意内容留在服务器端的系统里,比如数据库文件系统等等,随后才在浏览器中回显。这种是不需要社工的。
反射型的示意图在stage6这里

对于stage7的这道题,我要利用alert函数或者console.log()函数知道那个输入框容易被xss攻击

上面几个地方都有检测输入的是不是数字的,这个信用卡号的文本框是最容易被攻击的

4.3、构造反射型xss的恶意URL

stage7下面的stage8说stage7做的练习只是个“自xss”如果要做反射型xss我们需要构造一个URL给别人去点

用burpsuite拦截stage7的get包里面长这样

所以在地址栏里面这样输入

不过没有回显网页,给我回显的是数据包的源代码之类的东西,我们可以看到这个输出内容里面是有Javascript脚本的,只是没有被执行

应该是由于浏览器的某种安全机制在作祟
然后,我给课程设了reset,输入这个链接之后,红色的7果然变绿了,所以效果还是有的

4.4、Cross Site Scripting -> 10.dentify potential for DOM-Based XSS

domxss和传统反射型的xss的区别是,dom型的xss它的payload永远不会被送到服务器端
根据要求,这节课是让我在客户端重定向网页,找到test代码,那就先要找到给网页定向的JavaScript代码

这个start.mvc页面是这样的,

查看网页源码,点击它调用的js脚本,在js脚本里面ctrl+f查找test,

这就是光溜溜的一个test啊,那,start.mvc#后面接着的锚点直接改成test?试了一下没有出错,那就在这道题的文本框里面输入start.mvc#test
然后就成功了……这个题是我理解的不对么,好像有点过于简单了。

4.5、Cross Site Scripting -> 11.DOM-Based XSS


用dom型xss调用phoneHome函数获取一串随机数
在debugger里搜索到了源代码

然后在console里输入webgoat.customjs.phoneHome()

获得了随机数

输入文本框,成功!
然后,我们要怎么构造一个URL呢
比如刚才的第七题有一个xss漏洞,刚才也构造了URL,然后把script标签里面的语句换成webgoat.customjs.phoneHome();
根据代码的业务逻辑,它会在命令行回显一个phoneHomeinvoked然后把随机数提交到post数据包里

嗯,就这样,看到了输入URL之后命令行里面的输出,

但是随机数没有了,可能是因为这道题成功了?就不再显示随机数了?
也有可能是被我刚才一顿乱试的URL玩坏了,那样的话reset题目之后这个题就做不出来了啊……
那还是先不reset了
啊啊啊啊,我懂了,是刚才开的代理没有关掉,所以带着结果的post包被代理截住了
这样就好了

4.5、Cross Site Scripting -> 12.一套单选题

4.6、Cross Site Scripting (stored) -> 唯一一道存储型的题



这道题是让我在评论区里搞一个存储型xss然后调用phoneHome
在留言框里写然后命令行里就能看到随机数了

输入这个随机数,最后一道存储xss成功

5、csrf学习

大概就是,访问了一个网站,然后产生了cookie,带着这个cookie访问恶意网站就可以产生csrf攻击

5.1、csrf -> 3.Basic Get CSRF Exercise


根据题目描述这是一道夺旗的题,我要改掉请求来获取flag
点击提交会弹出一个新页面,上面的URL是这个样子的

看来要对这个URL动一动手脚才能得到flag
csrf=flase看起来很可疑
改掉,然后flag就出来了

成功

可是那个红方块没有变绿,很难受,难道是我的方法有问题么

5.2、csrf -> 4.Post a review on someone else’s behalf

这道题是让我代表当前用户发表评论,我正常输入了一堆乱敲的东西之后评论区的东西没有多,但是回显里提示我的request来自和我主机,就是站点一样的意思

那开启burpsuite改成不一样的呗


刷新页面,成功

5.3、csrf -> 7.CSRF and content-type

这个的要求是,我把它要求里面的表单信息提交上去,但是不能是这个页面提交的,
主要在于模拟一个站外调用未被保护的API的情境
那就写一个新的html

form的action是burpsuite拦截来的,隐藏元素的属性是要求的,最后js脚本调用表单进行提交
把这个html拖进浏览器里,出来flag,flag粘贴回去就能得到系统的congratulation

5.4、csrf -> 8.Login CSRF attack


按照提示新建用户,在那一页点提交

回到原来的用户,这个题就变绿了,可能是?让我体会一下这个过程???

二、问题回答

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

原理:

程序存在漏洞,这样会让DBMS执行从前台传过来的恶意代码成为可能。

防御:

目前我接触到的最好的办法(我感觉)是prepare-statement,我们在学Java的时候知道statement可以执行嵌入式SQL语句,而且基本所有可以注入的应用,它的后台都是用的statement。statement直接用前台传来的字符串拼接就查询,而preparestatement会执行预编译,应该是前台输入的地方会用占位符占住,对于数据库而言那个占位符就是一个变量了,然后前台传过来啥都塞进占位符里。
比如这个例子,正确答案是D

preparestatement会把整句带着注入代码的东西都当做用户名,然后给你以这个名字注册一个用户,注入根本没有机会发生。
当然还有很多办法,比如限制输入的长度、禁止输入违规的能引起SQL注入的字符。但是我还是感觉在后台写prepare-statement最骚。

XSS攻击的原理,如何防御

原理:

应用的前台允许让用户输入脚本,并且没有编码或者加密的措施

防御:

检测特殊字符,给字符做编码或者转义

CSRF攻击原理,如何防御

原理

有漏洞的网站只认用户的cookie,请求带着的cookie是这个用户的就给操作授予这个用户的权限,cookie被csrf一偷这个用户就完了

防御

我上面做的一道题修改的就是http请求的referer,这个referer是一种办法
就是说,对Referer(页面请求来源)进行判断,来源是本站就可以通过。但是通过我做的第二个csrf,很明显,如果有恶意代理拦截,那这个referer就可以被改,那就完蛋了
还有就是下发一个令牌(token),这个类似于挑战握手,服务器下发token给客户端,只有客户端有这个token,然后伪造的请求里面的token不对,就不行
但是如果token被偷了,那也完蛋了

三、实验总结与体会

为了准备ctf国赛的半决赛,我把所有的这三方面的题都刷了一遍,收获很大,除了最后一道SQL注入没做出来。感觉很有意思。我发现我可能是一个被pwn耽误了的web手。

posted @ 2019-05-25 12:09  ltl0501  阅读(758)  评论(0编辑  收藏  举报