1、项目1 Web服务器平台安装与配置【项目描述】本项目对Web服务器平台的安装和配置进行实训。本项目包含四个任务,首先安装Windows Server 2008企业版操作系统,然后进行PHP软件包的安装与配置,接下来对MySQL数据库进行安装与配置,最后完成Apache Web服务器的安装与配置。通过本项目的实训,可以解释Web服务器平台的主流的组合方式以及Web服务器平台的构成,可以实施Web服务器平台的安装与配置。【知识储备】Web服务器平台的组合多种多样。本书搭建的Web服务器环境,操作系统选用Windows Server 2008简体中文企业版,Web服务器使用Apache2.4和PHP
2、7.1,数据库使用MySQL5.5。【任务1-1】安装Web服务器操作系统 在本任务,进行Windows Server 2008简体中文企业版操作系统安装。对于有一定Linux/Unix操作系统使用经验的,推荐使用CentOS、Ununtu等作为Web服务器操作系统。推荐采用VMware软件的方式安装Windows Server 2008操作系统,在VMware中运行的操作系统称之为虚拟机,安装并运行了VMware虚拟机的操作系统称为宿主机。由于VMware Workstation Pro 10是支持32位操作系统的最后一个版本,因此本书使用了VMware Workstation Pro 10
3、.0.7版本的个人桌面版虚拟机软件。如果安装的Windows Server 2008 企业版操作系统是SP1版本,需要首先将操作系统升级到SP2版本(如果直接安装了Windows Server 2008 SP2操作系统则可以忽略此步骤)。升级到SP2版本后再安装Universal CRT补丁Windows6.0-KB2999226-x86.msu即可。另外,实施本书的项目和任务需要安装使用三种浏览器:自带的IE浏览器(7.0版本)、Firefox浏览器(52.8.0版本)和360安全浏览器(9.1.0.434版本)。另外,还需要安装Notepad+(7.5.6版本)用以编辑网页。【任务1-2】
4、安装并配置PHP 在本任务,下载安装并配置PHP及依赖的运行环境,所使用的版本为7.1.16。在PHP官网下载VC14 x86 Thread Safe版本php-7.1.16-Win32-VC14-x86.zip,将其解压到C:php-7.1.16-Win32-VC14-x86。安装Microsoft Visual C+2015运行环境Visual C+Redistributable for Visual Studio 2015_x86.exe。配置步骤如下:生成配置文件php.ini 更改配置文件自定义扩展目录 开启php_mysqli扩展的动态链接库 设置错误报警级别【任务1-3】安装并配
5、置MySQL 在本任务,下载安装并配置MySQL数据库软件。从官网下载MySQL4,版本可以选择msi安装版,也可以选择zip免安装版。本书使用的版本为免安装5.5.59-win32版本,安装配置过程如下:解压软件包 生成配置文件my.ini 给MySQL配置环境变量 将MySQL注册为系统服务 在命令提示符窗口输入并运行net start mysql启动服务 其它操作 设置密码 登录MySQL 查看字符集【任务1-4】安装并配置Apache 在本任务,下载安装并配置Apache Web服务器软件。从官网5下载Apache2.4,版本为httpd-2.4.33-o102o-x86-vc14-r
6、2.zip,并解压到路径C:Apache24。Apache的配置步骤如下:修改Apache的路径 禁止目录浏览 加载PHP 启动Apache 其它操作命令 测试【项目总结】本项目安装和配置的Windows 2008 Server企业版操作系统、Apache Web服务器、PHP和MySQL数据库构成了基本的Web服务器平台。需要注意的是,实际需求不同,即使选用相同的软件,Web服务器平台的配置要求也不同。本项目所搭建的平台,为本书的实训项目提供了运行测试环境。【拓展思考】你还了解哪些Web服务器平台组合?项目2 Web开发基础【项目描述】本项目对SQL语言和MySQL数据库,以及HTML、Ja
7、vaScript、CSS和PHP开发基础进行初步实训。本项目共包含三个任务,首先是基本SQL语言和MySQL数据库的的使用,然后综合使用HTML、CSS和JavaScript设计一个静态网页,最后使用PHP语言将其修改为动态网页。通过本项目的实训,可以编写基本的SQL语句管理MySQL数据库,可以解释HTML、JavaScript、CSS和PHP编写的网页,可以进行静态和动态PHP网页开发。【知识储备】数据库管理系统的基本概念 数据库管理系统DBMS是一种操纵和管理数据库的大型软件,用于建立、使用和维护数据库。常见的关系型数据库管理系统有Oracle、MySQL、SQL Server等,常见的
8、非关系型数据库管理系统有MongoDB、Redis、Memchache等。而数据库系统DBS是一个大的概念,不仅包括了DBMS和DB,还包括计算机操作系统以及数据库管理员等。关系型数据库是指采用了关系模型来组织数据的数据库,关系型数据库的最大特点就是事务的完整性和一致性,结构化查询语言是最重要的关系数据库操作语言 网页设计前端语言HTML、CSS和JavaScript 网页设计前端语言由浏览器负责解释执行,因此网页文件的源代码会从Web服务器发送到浏览器。层叠样式表CSS是一种用来表现HTML等文件样式的一种计算机语言,它也是一种描述性的标记语言。CSS为HTML标记语言提供了一种样式描述,定
9、义了其中元素的显示方式。这样,HTML元素用于网页内容的表达,CSS则是定义如何显示HTML元素,两个共同作用让网页内容实现需要的布局样式。JavaScript编程语言是一种脚本语言,主要用来向HTML页面添加交互行为 网页设计后端语言PHP 后端语言由服务器负责解释执行,结果以纯HTML的形式返回给浏览器。因此PHP文件不传递到用户端,用户端无法看到其源代码。PHP文件不需要编译成二进制文件,因此PHP编程语言也是一种脚本程序语言。PHP语言是一种应用非常广泛的动态网页设计程序语言。动态网页是指跟静态网页相对的一种网页编程技术。一般来说,PHP语言脚本需要和HTML标签混合编写。【任务2-1
10、】MySQL数据库的使用 在本任务,使用MySQL数据库管理系统完成数据库的创建和数据表的创建,并对数据表的记录进行增删改查操作。数据库的操作使用DDL语句。首先在命令提示符窗口登录MySQL。登录方法参见图 1-7所示。登录成功之后,首先创建一个数据库firstlab。使用的SQL语句为:CREATE DATABASE firstlab;注意SQL语句以分号结束。数据库创建成功之后,使用SQL语句USE firstlab;将当前数据库切换到firstlab。数据表定义 数据表的定义使用DDL语句。继续在该数据库中创建一个用户表users。该表包括三个字段,其结构如表2-1所示 数据表的操作
11、数据表的增、删、改、查使用DML语句。首先给users表添加一条记录,使用如下语句:INSERT INTO users(username,passcode)VALUES(admin,admin123);记录的查询使用如下语句:SELECT*FROM users;对上面插入的这条记录进行更新,将email字段修改为。SQL语句如下:UPDATE users SET email= WHERE id=1;最后讨论一下记录的删除。通常情况下表之间存在外键约束,删除记录就会出现删除异常。所以在实际应用中常常不会进行记录的删除,一方面避免外键关联造成的删除异常,另一方面保护了数据的完整性。MySQL数据库
12、的权限管理 MySQL数据库支持用户权限管理,大大增加了数据库的安全性。比如,如果只允许你执行select操作,那么你就不能执行update、insert等操作。如果只允许你从个IP地址连接MySQL数据库,那么你就不能从其它IP地址连接。【任务2-2】静态网页开发 在本任务,综合使用HTML、CSS和JavaScript语言设计一个网页,在网页中用一个表格显示用户的账号、密码、电子邮件地址等信息。创建HTML静态网页user.html 在Apache的网站根目录C:Apache24htdocs下新建一个文件夹user作为本项目的网站目录。打开Notepad+,新建一个文件,点击“编码”菜单并
13、将文件编码设置为“使用UTF-8编码”CSS的使用 CSS可以在HTML文件中使用混合编写的方式,也可以使用单独的CSS文件。使用单独CSS文件的好处是方便对网站的全局样式进行定义,实现所有网页风格样式的统一。要使用CSS对HTML页面中的元素实现一对一,一对多或者多对一的控制,就需要用到CSS选择器(或称为CSS选择符)以及一条或多条声明。即CSS选择器和声明组成了CSS的规则。在user.html文档中添加一些HTML标签,给一些标签添加ID或者类属性,并设置元素的CSS规则 接下来创建一个公共的main.css文件,以便将所有网页全局的HTML元素进行格式化 使用JavaScript显示
14、当前时间 在user.html的第44行之后添加一行HTML的代码用来显示当前时间 然后在第13行之后添加一段JavaScript脚本用来得到并控制时间的显示 这样,就会在页脚显示当前的年月日和时刻。虽然当前时间不停的在变化,但是该网页仍然只是静态网页。【任务2-3】PHP动态网页开发 本任务在静态网页user.html的基础上,利用PHP脚本实现从数据库firstlab的users表中读取信息并在网页表格中展示。将user.html复制并重命名为user_php.html,所做的修改工作均在user_php.html网页文件中进行。从本任务可以发现,动态网页虽然不需要修改网页源代码,但是网页
15、的内容会随着数据库中数据的变化而变化。【项目总结】本项目为本书将要进行的Web漏洞及防护项目准备了基本的数据库和SQL语言基础,以及HTML、JavaScript、CSS前端开发和PHP语言后端开发基础。在生产环境需要注意数据库的权限管理问题,数据库使用的字符集应和HTML文件、CSS文件、JavaScript文件和PHP脚本文件保持一致以避免出现显示乱码。【拓展思考】PHP代码可以混写CSS吗?尝试在自定义的outputusers()函数中将状态为0的记录用红色显示。如何给MySQL数据库的firstuser用户收回create创建表格的权限?项目3 万能密码登录Post型注入攻击【项目描述
16、】本项目对Post型SQL注入攻击和防护进行实训。本项目包含四个任务,首先建立建立用户信息数据库,然后开发一个基于Session验证的用户登录功能网站,并在网页表单使用Post的方式提交用户参数。接下来实现基于SQL注入方式的万能密码登录。最后通过分析万能密码SQL注入的原理,实现对Post型SQL注入攻击的多种防护方式。通过本项目的实训,可以解释和分析万能密码登录漏洞为例子的Post型SQL注入原理及危害,应用多种方式实现SQL注入攻击的防护。【知识储备】HTML的Post与Get提交信息方式 Post型SQL注入攻击使用了HTML的Post提交信息方式。在HTML中,经常会用表单进行信息的
17、收集,然后提交给服务器进行处理。HTML提交信息的方式有Get和Post两种。Get方式方式Post方式方式在在URL显示表单参数的显示表单参数的key/value值值不在URL里显示表单的数据长度有限制,只适合有少量参数的表单长度有限制,只适合有少量参数的表单表单提交的信息没有长度限制历史参数保留在浏览器历史中历史参数保留在浏览器历史中参数不会保存在浏览器历史中可以通过保留可以通过保留URL的方式保存数据的方式保存数据不能通过保留URL保存数据刷新不会重新提交刷新不会重新提交刷新会重新提交表单的数据集的值必须为表单的数据集的值必须为ASCII字符字符没有限制表 3 1 Post方式与Get方
18、式的主要区别 Session机制的原理 HTTP协议是无状态的,也就是说,客户端的每个HTTP请求都是独立的,与前面或者后面的HTTP请求都没有直接联系。这样的好处是,服务器不需要为每个连接维持状态而消耗大量资源。最初设计的HTTP协议只是用来浏览静态文件,无状态特点已经足够。但是随着Web应用的发展,需要变得有状态,比如需要保持用户的登录状态。Session机制就是用来保存用户登录状态的。用户提交登录信息并通过验证之后,在服务器将用户信息保存在Session变量中,在用户的浏览器则保存这个Session的ID(即SessionID)。当用户再次访问这个服务器时会将此SessionID提交,服
19、务器便可以验证此SessionID是否存在于Session变量中,进而判断是否为登录用户 基于Session机制的Web登录验证过程 用户账号信息提交 在Web服务器建立Session会话 退出登录 万能密码SQL注入攻击的原理 所谓万能密码,就是通过在输入的用户名或者密码构造出一个特殊的SQL语句,破坏原有的SQL语句结构和逻辑,最终达到欺骗服务器执行恶意的SQL命令,进而绕过权限检查登录系统。由于用户登录基本都是使用HTML的Post方式提交账号和密码等信息,因此万能密码登录是一种典型的Post型SQL注入攻击。SQL注入攻击的危害 虽然Post型和Get型注入攻击在方式上有所区别,但都是
20、通过破坏正常的SQL语句结构,实现对数据库非正常增删改查。SQL注入攻击的危害主要体现在:绕过登录检查;获取、篡改数据库信息;篡改网页内容、网页挂马;控制网站、甚至整个服务器等。【任务3-1】创建数据库 本任务采用SQL脚本的方式创建数据库lab。并在该数据库中建立表users,最后插入两条记录。在Apache的网站根目录C:Apache24htdocs下新建一个文件夹logintest作为本项目的网站目录。基于SQL脚本的方式创建数据库有两个步骤,分别是:创建SQL脚本 将脚本文件导入到数据库【任务3-2】建立基于Session验证的用户登录网站 在本任务,分别创建用户登录HTML页面和验证
21、登录的PHP后端页面,以实现用户登录功能。用户登录成功之后会跳转到欢迎页面,并创建退出登录页面销毁用户Session。最后进行功能测试,以验证所设计的功能。3-2-1 任务实现 创建用户登录页面login.html 设置编码方式为UTF8并保存 登录验证后端页面 欢迎页面 销毁session页面 3-2-2 功能测试 打开浏览器,在地址栏输入服务器的地址和相对路径以及文件名,即可访问。本书默认的浏览器客户端都是在Web服务器的本地访问,在地址栏输入URL的主机地址都是localhost或者127.0.0.1,比如输入http:/localhost/logintest/login.html打开登
22、录页面 在该页面点击超链接“欢迎访问”,进入welcome页面 在该页面点击超链接“退出登录”,进入logout页面注销登录【任务3-3】万能密码SQL注入攻击测试 在本任务,利用万能密码进行Post型SQL注入攻击测试,绕过登录检查进入欢迎页面。并对万能密码注入攻击的原理进行分析,最后讨论其它形式的万能密码SQL注入及其原理。3-3-1 测试过程 用户名注入 在Username输入:or 1=1 or,Password随便输入(比如输入123),点击Submit按钮则可以登录进入系统 注意:引号为英文的单引号 在欢迎登录页面,可以看到登录用户为admin 密码注入 在Username随便输入
23、(比如输入admin),在Password输入or 1=1,也可以登录系统 其效果与用户名注入方式相同 3-3-2 其它形式的万能密码 or=or 注意都是单引号 将其代入到SQL语句的变量后,则查询语句变成了:select*from users where username=or=or and passcode=123 该语句的条件是恒成立的,因此查询的结果也是users表的全部记录-注释 也可以使用注释的方式实现万能密码,比如or 1=1-(注意:两个连续的减号后面必须有一个空格)。将其代入到SQL语句的变量后,则查询语句变成了:select*from users where userna
24、me=or 1=1-and passcode=123 在SQL语句中,两个减号表示后面的语句被注释掉。因此该查询语句变成了:select*from users where username=or 1=1 该条件是恒成立的,查询的结果也是users表的全部记录#注释 注释型的万能密码也可以说使用#(即英文的井号),比如or 1=1#。将其代入到SQL语句的变量后,则查询语句变成了:select*from users where username=or 1=1#and passcode=123 去掉注释后的查询语句变成了:select*from users where username=or 1=
25、1 该语句的查询效果与以上相同 3-3-3 测试分析 在用户名注入情况下,将字符串or 1=1 or代入到check_login.php页面第16行的变量$username,将字符串123代入到变量$passwd,则SQL查询语句select*from users where username=$username and passcode=$passwd 变成了:select*from users where username=or 1=1 or and passcode=123 注意:为两个连续的单引号。可见,字符串or 1=1 or的第一个单引号闭合$username的第一个单引号,第二个
26、单引号闭合$username的第二个单引号。查询条件or 1=1恒成立。在SQL查询语句中,and的运算优先级大于or。故在上述SQL查询语句的where子句中,虽然username=为假,passcode=123为假,但是1=1为真,故where子句的条件为永真。在第2种情况下,SQL查询语句则变成了:select*from users where username=admin and passcode=or 1=1 其分析与上一种情况类似。从以上分析可以发现,引起Post型SQL注入的根源在于,PHP代码使用了SQL语句拼接的方式进行数据库操作,而拼接所使用的变量由Post方式提交。因此,
27、用户可以通过提交包含特殊SQL分界符等内容,使得正常的SQL查询、更新、插入等语句的结构和逻辑功能发生变化,反而执行了攻击者设计的逻辑,造成对系统破坏或者非授权的访问。【任务3-4】万能密码SQL注入攻击防护 在本任务,实现对万能密码SQL注入攻击的防护的四种方式,并验证防护效果。万能密码的防护需要限制用户的输入,可以从两个方面着手。一方面,可以使用正则表达式限制用户输入;另一方面,可以使用PHP的安全函数。3-4-1 使用正则表达式限制用户输入 使用正则表达式将用户输入限制为指定字符组合。这种处理方式是很多网站普遍采用的方式。在用户注册时,将用户名限制为英文字母、数字和下划线的组合,避免出现
28、单引号等可以引起SQL注入的符号出现,从而避免万能密码攻击。正则表达式的规则说明:头尾两个斜杠/是正则表达式的限定符,表示两个斜杠之间就是正则内容;和$是行定位符,分别用来匹配字符串的开头和结尾;中括号括住的内容只匹配一个单一的字符,比如a-z表示匹配a到z的单个字符;在花括号里面限制字符出现的个数,比如a-z5,16表示匹配a到z的5到16个字符。使用正则表达式检查用户输入的用户名,需要在文件check_login.php中第14行开始添加如下内容:int preg_match(string$pattern,string$subject)函数用于执行一个正则表达式匹配。其中参数$patter
29、n为要搜索的模式,字符串形式;$subject为输入的字符串。函数preg_match()在第一次匹配后将会停止搜索,如果出现不匹配的字符将返回0 由于正则表达式限制为5到16个字母、数字、或者下划线组合,如果在用户名中输入单引号,或者长度不在范围,都会得到“用户名输入格式错误”的提示。对输入密码的检查可以使用同样的方法。3-4-2 使用PHP的转义函数 addslashes()函数 addslashes()函数返回在预定义字符之前添加反斜杠的字符串 mysql_escape_string()或者mysql_real_escape_string()函数 二者都是实现转义SQL语句中的字符串中的
30、特殊字符,差别较小。在PHP 5和PHP 7中升级为mysqli_escape_string()和mysqli_real_escape_string()3-4-3 MySQLi参数化查询 参数化查询是指与数据库连接并访问数据时,在需要填入数值或数据的地方,使用参数来给值。在使用参数化查询的情况下,数据库服务器不会将参数的内容视为SQL指令的一部分来处理,而是在数据库完成SQL指令的编译后,再代入参数运行。因此就算参数中有恶意的指令,由于已经编译完成,就不会被数据库运行。这个方法目前已被视为最有效的SQL注入攻击防护方式。PHP提供了三种访问MySQL数据库的扩展,即MySQL,MySQLi和P
31、DO。MySQL扩展不支持参数化查询,MySQLi和PHP数据对象(PHP Data Object,PDO)这两个新扩展都支持参数化查询。3-4-4 PDO参数化查询 MySQLi扩展虽然比MySQL扩展更加优化且方便从MySQL扩展迁移,但是它只支持MySQL数据库。PDO扩展对比MySQLi扩展的优点是,它是与关系数据库类型无关的,可以支持十几种数据库扩展,因此可以很方便的切换数据库,比如从MySQL切换到PostgreSQL、MS SQL Server等。【项目总结】本项目以万能密码登录为例,对Post型SQL注入进行漏洞重现、攻击测试和漏洞分析,给出了多种防护方案并进行防护效果测试。攻
32、击测试分析表明,对HTML Post方式提交的内容,使用传统字符串拼接方式访问数据库是Post型SQL注入漏洞的根源。使用基于白名单的正则表达式过滤用户提交的用户名和密码(如果密码进行了加密或者散列处理则不需要过滤),可以防护万能密码登录漏洞,但防护Post提交的其它变量内容还需要做大量的工作。使用转义函数可以防护Post型SQL注入,如果网站存在Post型SQL注入漏洞,使用转义函数比正则表达式过滤方便,但要注意宽字节字符集存在的风险。使用MySQLi或者PDO参数化查询可以从根本上防护Post型SQL查询注入攻击,在编写数据库SQL查询PHP代码时推荐使用二者之一。【拓展思考】如果执行数据
33、库的查询语句为:$sql=select*from users where username=.$username.and passcode=.$passwd.;该如何构造万能密码?提示:由于点号起连接作用,因此该SQL查询语句可以分解成select*from users where username=+$username+and passcode=+$passwd+的形式。如果Username输入为admin,Password输入admin123,由于双引号的功能是定义字符串的,那么去掉双引号后该查询语句实际执行的内容为select*from users where username=admi
34、n and passcode=admin123。你还了解哪些查询语句的形式?如果构造对应的万能密码?项目4 数据库暴库Get型注入攻击【项目描述】本项目对Get型SQL注入攻击和防护进行实训。本项目包含了四个任务,首先建立数据库用于信息查询,然后开发一个基于Get型查询功能的网站,接下来利用Get型SQL注入实现数据库暴库,最后分析Get型SQL注入攻击的原理,提出并实现对Get型SQL注入攻击的防护。通过本项目实训,可以解释和分析Get型SQL注入漏洞对数据库进行暴库攻击的原理及危害,应用参数化查询功能实现Get型SQL注入攻击的防护。【知识储备】HTML Get方式参数提交原理 Get型S
35、QL注入攻击使用了HTML的Get提交信息方式。Get方式将表单中的数据按照“变量”=“值”的形式,使用“?”连接添加到action所指向URL的后面。如果有多个变量,各个变量之间使用“&”连接。Get方式提交的表单只支持ASCII字符,非ASCII字符必须使用URL编码的方式传递,例如中文。另外一些特殊的字符也需要进行URL编码,如果“值”字符串中包含了=或者&,必须将引起歧义的&和=符号进行编码转义。URL编码的格式是用百分号加字符ASCII码的十六进制表示。数据库暴库的原理 数据库暴库是Get型SQL注入的常用攻击。暴库就是通过数据库的SQL注入等漏洞得到数据库的内容。Get方式的参数提
36、交多用于数据库的查询操作,并在页面显示查询结果。因此,常常可以利用Get方式查询数据库实现暴库。数据库的UNION操作符用于合并两个或多个SELECT语句的结果集,如果存在SQL注入漏洞,则可以构造一个UNION查询语句提交给数据库查询页面,进而实现数据库暴库。Get型和Post型SQL注入攻击的区别 二者从危害性方面很难对比大小,但方式完全不同。通过对Post与Get提交信息方式的区别可知,Post型是通过Form表单提交数据,而Get型是将数据的按照“变量”=“值”的形式,使用“?”连接添加到action所指向URL的后面。因此,Post型SQL注入会发生在页面表单提交信息的情况下,而Ge
37、t型SQL注入往往发生在通过超连接方式向其它网页传递参数的情况下。【任务4-1】创建数据库 本任务采用SQL脚本的方式创建数据库lab。在该数据库中建立表books,最后插入两条记录。在Apache的网站根目录C:Apache24htdocs下新建一个文件夹get作为本项目的网站目录。创建SQL脚本 将脚本文件导入到数据库【任务4-2】建立Get方式查询的网站 在本任务,创建一个基于Get方式信息查询功能的网页并进行功能测试。4-2-1 任务实现 首先将项目3网站目录下的con_database.php复制到C:Apache24htdocsget目录下。然后在get目录下新建一个index.p
38、hp网页文件 4-2-2 功能测试 打开浏览器,在地址栏输入服务器的地址和相对路径以及文件名,即可访问。如果是本地访问,可以打开http:/localhost/get/index.php?id=1查询第一条记录,如图 4 2所示。其中“?”用来连接URL地址和Get方式传递的变量id,id的值为1。【任务4-3】数据库暴库攻击测试 在本任务,进行Get方式SQL注入暴库攻击测试,并对攻击原理进行分析。4-3-1 暴数据库 在浏览器地址栏输入以下内容:http:/localhost/get/index.php?id=-1%27union%20select%201,group_concat(sch
39、ema_name),3%20from%20information_schema.schemata-+其中,id=-1,则查询记录为空;%27是将单引号用URL编码形式表示的ASCII字符(百分号加两位十六进制格式),和index.php网页的第19行的id=$id左边的单引号形成闭合。%20表示空格。由于URL结尾的空格会被浏览器忽略,故使用了URL特殊字符转义+表示空格。此时的SQL语句为SELECT*FROM books WHERE id=-1union select 1,group_concat(schema_name),3 from information_schema.schemat
40、a-LIMIT 0,1。由于-注释掉了后面的内容,因此该SQL语句等价于:SELECT*FROM books WHERE id=-1union select 1,group_concat(schema_name),3 from information_schema.schemata 其中,union运算符将多个select语句的结果组合成一个结果集,要求查询中的列数必须要相同。由于books表有三列,因此union select也要查询了三个属性,其中1和3不是表的属性,目的是凑够三个属性,也可以是其它数字或者字符串。information_schema数据库是MySQL系统内置的数据库,保存
41、的是本数据库实例中其它所有数据库的信息,information_schema的schemata表提供的是数据库的信息,schemata表的schema_name提供了数据库的名称,使用group_concat()函数把所有的数据库名称值组合起来。注入攻击的结果如图 4-3所示。从以上结果可以看出,在Book name中出现了整个MySQL中所有的数据库。Author的内容为3,是由于union select的第三个属性为3。图 4 3 注入攻击暴数据库 4-3-2 暴lab数据库的数据表 在浏览器地址栏输入并打开以下内容:http:/localhost/get/index.php?id=-1%
42、27union%20select%201,group_concat(table_name),3%20from%20information_schema.tables%20where%20table_schema=%27lab%27-+此时,index.php网页第19行的SQL语句等价于:SELECT*FROM books WHERE id=-1union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=lab 其中information_schema的tables提供的
43、是数据表的信息。注入攻击的结果如图 4-4所示:从以上结果可以看出,在Book name中出现了lab数据库的所有数据表。图 4 4 注入攻击暴数据表 4-3-3 暴users表的所有列 在浏览器地址栏输入以下内容:http:/localhost/get/index.php?id=-1%27union%20select%201,group_concat(column_name),3%20from%20information_schema.columns%20where%20table_name=%27users%27-+此时,index.php网页第19行的SQL语句等价于:SELECT*FR
44、OM books WHERE id=-1union select 1,group_concat(column_name),3 from information_schema.columns where table_name=users 其中information_schema的columns表提供的是数据表的列的信息。注入攻击的结果如图 4-5所示:图 4 5 注入攻击暴数据表的所有列 4-3-4 暴users表的数据 在浏览器地址栏输入以下内容:http:/localhost/get/index.php?id=-1%27union%20select%201,username,passcode
45、%20from%20users%20where%20id=1-+此时,index.php网页第19行的SQL语句等价于:SELECT*FROM books WHERE id=-1union select 1,username,passcode from users where id=1 注入攻击的结果如图 4-6所示:可以发现,该注入攻击把users表的第一条记录的用户名和密码查询出来了。图 4 6 注入攻击暴表的数据 4-3-5 测试分析 通过以上攻击手段发现,只要网站存在注入攻击漏洞,整个MySQL数据库的都可以被注入攻击后暴露出来。以上攻击手段均采用了union联合查询,union操作符
46、用于合并两个或多个select语句的结果集。需要注意的是union内部的select语句必须拥有相同数量的列,列也必须拥有相似的数据类型。由于lab数据库的books表有3列(三个字段),因此union select语句也选择了三个字段。将SQL查询语句SELECT*FROM books WHERE id=-1union select 1,group_concat(schema_name),3 from information_schema.schemata放在数据库中进行查询,其结果如图 4-7所示 由于数据库schema_name很多,需要在一行中全部输出,因此使用了group_conca
47、t()函数把schema_name列的所有值组合起来。如果不使用group_concat,其查询结果就有很多行,无法将bookname字段通过网页显示出来。SQL语句SELECT*FROM books WHERE id=-1union select 1,schema_name,3 from information_schema.schemata的查询结果如图 4-8所示 Union select语句中的1、3只是起到补充字段的作用,使得union内部的select语句拥有相同数量的列。暴数据表、表的列以及表的数据都是相同的道理。需要注意的是,这种攻击只是SQL注入攻击方法的一种情况。只要存在注
48、入点,数据库就不安全。因此注入攻击需要引起高度重视。【任务4-4】Get型攻击防护 在本任务,对Get型SQL注入攻击实现两种防护方式,并验证防护效果。由于Get方式是向Web服务器提交参数的重要方式且多数情况下参数比较复杂,URL编码、大小写等都可以绕过黑名单过滤,因此不推荐黑白名单的方式,尤其是黑名单的方式防护。4-4-1 使用PHP转义函数 mysqli_escape_string()转义函数方式应用比较简单,请自行实现,但需要注意宽字符绕过的风险。另外,这种方式仍然属于SQL语句拼接的方式,因此也不推荐使用。4-4-2 MySQLi参数化查询 MySQLi参数化查询和PDO参数化查询都
49、能防护Get型攻击,下面给出MySQLi参数化查询的网页代码,并保存为index_mysqli.php。【项目总结】本项目以数据库暴库攻击为例,对Get型SQL注入进行漏洞重现、攻击测试和漏洞分析,给出了PHP转义函数和MySQLi参数化查询的防护方案并进行防护效果测试。攻击测试分析表明,对HTML Get方式提交的内容,使用传统字符串拼接方式访问数据库是Get型SQL注入漏洞的根源。使用转义函数可以防护Get型SQL注入,但要注意宽字节字符集存在的风险。使用MySQLi或者PDO参数化查询可以从根本上防护Get型SQL查询注入攻击。【拓展思考】怎样对Get方式实现PDO参数化查询?如果PHP
50、的查询语句为:$sql=SELECT*FROM books WHERE id=$id LIMIT 0,1;该如何实现注入攻击?(注意,$id没有引号)你还了解哪些Get型注入攻击方式?项目5 更新密码二阶注入攻击【项目描述】本项目对数据库二阶SQL注入攻击和防护进行实训。本项目包含三个任务,首先建立一个实现密码更新功能的网站,接下来利用更新密码功能的二阶SQL注入攻击实现对数据库中其它用户账号密码的修改,最后分析了二阶SQL注入攻击的原理并使用转义函数和参数化更新实现二阶注入防护。通过本项目的实训,可以解释和分析二阶SQL注入漏洞产生的原理及危害,能够应用转义处理或者参数化更新实现二阶SQL注