软件安全实验——lab8(SQL注入)(上)(旧虚拟机seedubuntu9版本实验)
Posted 大灬白
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了软件安全实验——lab8(SQL注入)(上)(旧虚拟机seedubuntu9版本实验)相关的知识,希望对你有一定的参考价值。
目录标题
2、实验室环境
您需要为这个实验室使用我们提供的虚拟机映像。支持这个实验室的虚拟机映像的名称为seedubuntu9 -August -2010,它是在2010年8月构建的。如果您碰巧有我们预构建的VM镜像的旧版本,您需要下载最新版本,因为旧版本不适用于本实验室。请登录我们的SEED网页(http://www.cis.syr.edu/˜wedu/seed/)获取VM镜像。
2.1环境配置
在这个实验中,我们需要三样东西:(1)Firefox网络浏览器,(2)apache网络服务器,(3)phpBB2留言板网络应用程序。对于浏览器,我们需要使用几个 Firefox插件来检查和/或修改HTTP请求和响应。提供给您的预构建的 Ubuntu虚拟机镜像已经安装了带有所需扩展的Firefox浏览器。
启动Apache服务器。apache web服务器也包含在预构建的Ubuntu镜像中。但是,默认情况下web服务器是不启动的。你必须首先使用以下命令启动web服务器:
% sudo service apache2 start
phpBB2 Web应用程序。phpBB2 web应用程序已经在预构建的Ubuntu虚拟机镜像中设置好了。我们还在phpBB2服务器上创建了几个用户帐户。密码信息可以从首页的帖子中获取。您可以使用以下URL访问phpBB2服务器(需要无启动apache服务器):
`http://www.sqllabmysqlphpbb.com`
web应用程序的源代码在/var/www/SQL/SQLLabMysqlPhpbb/。
配置DNS。这个URL只能从虚拟机内部访问,因为我们修改了 /etc/hosts文件,将域名(www.sqllabmysqlphpbb.com)映射到虚拟机的本地IP地址(127.0.0.1)。您可以使用 /etc/hosts将任何域名映射到特定的P地址例如,在 /etc/hosts文件中添加如下内容,将http:/www.example.com 映射到本地P地址。
127.0.0.1 www.example.com
因此,如果您的 web 服务器和浏览器运行在两台不同的机器上,您需要相应地修改浏览器机器上的/etc/hosts文件,将 www.sqllabmysqlphpbb.com映射到web服务器的地址。
配置Apache服务器。在预构建的VM映像中,我们使用Apache服务器托管SEED实验室中使用的所有网站。Apache中的基于名称的虚拟主机特性可以用于在同一台机器上托管多个网站(或url)。在""letc/ apache2lsites-availab le"目录下有一个名为default的配置文件,其中包含了必要的配置指令:
<VirtualHost *>
ServerName http://www.example1.com
DocumentRoot /var/www/Example_1/
</VirtualHost>
<VirtualHost *>
ServerName http://www.example2.com
DocumentRoot /var/www/Example_2/
</VirtualHost>
您可以通过访问上述目录中的源代码来修改 web应用程序。例如,使用上面的配置,可以通过修改目录/var/www/Example_1/中的源来修改web应用程序http://www.example1.com.
开启Apache服务器
2.2关闭对策
PHP提供了一种自动防御SQL注入攻击的机制。这个方法被称为magic quote,更多细节将在Task 3 中介绍。让我们先关闭此保护(此保护方法在PHP 5.3.0版本后己弃用)。
1. 打开/etc/php5/apache2/php.ini.
2. 找到这一行: magic quotes gpc = On.
3. 把它改成这样: magic quotes gpc = Off.
4. 重启apache服务通过"sudo service apache2 restart".
关闭对策
3、实验室的任务
3.1 Task 1(30分):针对SELECT语句的SQL注入攻击
在这个任务中,你将使用虚拟机中通过URL www.sqllabmysqlphpbb.com访问的 web应用程序,该URL是phpBB2配置了MysQL数据库。在开始使用 phpBB2之前,系统会要求您登录。身份验证由服务器端的 login.php 实现。这个程序将向用户显示一个登录窗口,并要求用户输入他们的用户名和密码。登录界面如下所示:
一旦用户输入了用户名和密码,login.php程序将使用用户提供的数据来确定它们是否与数据库中任何记录的用户名和密码字段匹配。如果匹配,则意味着用户提供了正确的用户名和密码组合,应该允许登录。与大多数其他web应用程序一样,PHP程序使用标准的SQL语言与后端数据库进行交互。在phpBB2中,login.php中构造了以下SQL查询来验证用户:
SELECT user_id, username, user_password, user_active, user_level,
user_login_tries, user_last_login_try
FROM USERS_TABLE
WHERE username = ’$username’ AND user_password = ’md5($password)’;
if (found one record)
then {allow the user to login}
在上面的 SQL语句,用户表是一个宏观的php将取代了用户表名称:phpbb用户,用户名是一个变量,持有美元字符串输入用户名的文本框,密码是一个变量保存字符串输入密码文本框。用户在这两个文本框中的输入直接放在SQL查询字符串中。
登录SQL注入攻击:该查询存在SQL注入漏洞。您能否利用此漏洞实现以下目标?
· 在不知道正确密码的情况下,你能登录别人的账户吗?
· 你能找到一种方法来修改数据库(仍然使用上面的 SQL查询)?例如,您是否可以向数据库添加一个新帐户,或者删除一个现有的用户帐户?显然,上面的SQL语句是查询语句,不能更新数据库。但是,使用SQL注入,可以将上面的语句转换为两个语句,第二个语句是更新语句。请尝试此方法,看看是否能成功更新数据库。
说实话,我们无法达到更新的目标。这是因为 MysQL 中实现了一种特殊的防御机制。在报告中,您应该向我们展示您为修改数据库所做的努力。你应该找出攻击失败的原因,MysQL有什么机制阻止了这样的攻击你可以从网上寻找证据(二手的)来支持你的结论。然而,第一手证据会得到更多的分数(使用你自己的创造力去找到第一手证据)。如果你找到了成功攻击的方法,你将获得额外分数。
Login.php页面源代码
(1)不用密码登陆管理员账号:
admin’#
(2)使用update语句更新用户
结果失败
是因为,在MYSQL中,线上容易不小心UPDATE,DELETE的时候,无加限制条件,从而引起灾难。所以MYSQL有开关可以防止误操作,一定程度上减少发生机会。可以设置:sql_safe_updates。
其中:当sql_safe_updates设置为1时,update:要有where,并查询条件必须使用为索引字段,或者使用limit,或者两个条件同时存在,才能正常执行。delete:where条件中带有索引字段可删除,where中查询条件不是索引,得必须有limit。主要是防止update和deLete没有使用索引导致变更及删除大量数据。参数默认值为0。
3.2 Task 2(30分): SQL注入的UPDATE语句
当用户想要在phpBB2中更新他们的配置文件时,他们可以单击Profile链接,然后填写一个表单来更新配置文件信息。用户向服务器发送更新请求后,将在includelusercp_register.php_中构造一条updatesQL语句。这条语句的目的是修改_phpbb_users表中当前用户的配亶文件信息。此SQL语句中存在sQL注入漏洞。请找到漏洞,然后利用它做以下工作:
·在不知道密码的情况下更改其他用户的个人资料。例如,如果您以Alice身份登录,那么您的目标是使用该漏洞修改Ted的个人信息,包括Ted的密码。攻击之后,你应该可以登录泰德的账户了。”
在修改密码时,修改其他人的密码:
将用户名为:hyh的用户密码修改为123
登陆成功:
3.3 Task 3 (40 Points):对策
SQL注入漏洞的根本问题是代码与数据无法分离。当构造SQL语句时,程序(例如PHP程序)知道哪些部分是数据,哪些部分是代码。不幸的是,当SQL语句被发送到数据库时,边界已经消失了;如果将代码注入到数据字段中,SQL解释器看到的边界可能与原始边界不同。要解决这个问题,确保边界视图在服务器端代码和数据库中是一致的是很重要的。有很多方法可以实现这个目标。
任务3.3.1
·任务3.1:使用魔术引号转义特殊字符在PHP代码中,如果数据变量是字符串类型,则需要用一对单引号符号()将其括起来。例如,在上面列出的 SQL查询中,我们看到usermame = ' u s e r n a m e ′ 。 围 绕 username '。围绕 username′。围绕usemame 的单引号基本上是“尝试”将 u s e r m a m e 变 量 中 的 数 据 与 代 码 分 离 。 不 幸 的 是 , 如 果 usermame变量中的数据与代码分离。不幸的是,如果 usermame变量中的数据与代码分离。不幸的是,如果usemame 的内容包含任何单引号,这种分离将失败。因此,我们需要一种机制来告诉数据库,Susemame中的单引号应该被视为数据的一部分,而不是SQL中的特殊字符。我们需要做的就是在单引号前添加一个反斜杠/。
PHP提供了一种机制,可以在单引号()、双引号(")、反斜杠()和NULL字符前自动添加反斜杠。如果打开这个选项,用户输入的所有字符都将自动转义。要打开这个选项,请进入/etc/php5/apache2/php.ini,并添加magic_quotes_gcc = On(该选项已经在VM中提供给你)。记住,如果你更新 php.ini,你需要通过运行“sudo service apache2 restart”重启 apache 服务器;否则,您的更改将不会生效。
请打开/关闭魔法报价机制,看看它如何帮助保护。请注意,从PHP 5.3.0开始(我们提供的虚拟机版本是5.2.6),该特性己被弃用,原因如下:
——可移植性:假设它是打开的,或关闭的,将影响可移植性。大多数代码必须使用一个名为get_magic_quotes_gpc()的函致来检查,并相应地编写代码。
——性能和不便:并非所有用户输入都用于SQL查询,因此强制转义所有数据不仅会影响性能,而且当一些数据不应该转义时,也会变得令人讨厌。
打开php的保护机制:
重启apache服务器
重复Task 1和Task 2的攻击
task 1
task 2
结果都攻击失败了
任务3.3.2
·任务3.2:使用addslashes()转义特殊字符。一个名为addslashes()的PHP函数也可以实现magic quote的功能。原来的phpBB2代码使用addslashes()来防御SQL注入攻击,如果没有打开magic quote。请查看/var/www/SQL/SQLLabMysqlPhpbb中的common.php 文件(登录时包含common.php)。Php,因此只要 login.php被执行,它就会被执行)。我们实际上注释掉了phpBB2中的保护,以使SQL注入成为可能。请重新打开保护,从下面的行中删除“and FALSE”以查看区别(我们添加了“and FALSE”以绕过这段代码)。请描述这个保护方案如何帮助您抵御SQL注入攻击:
if( !get_magic_quotes_gpc() and FALSE )
在移除"and False"之后,如果魔法报价机制被关闭,if-block 内的对策将被执行1。为了帮助描述您的观察结果,您应该打印SQL查询,并查看该机制如何影响查询。请到指南部分学习如何在 PHP程序中打印信息。
移除"and False”
任务3.3.3
·任务3.3:使用mysql真实转义字符串转义特殊字符。为了防止SQL注入,更好的转义数据的方法是使用数据库特定的转义机制,而不是依赖神奇的引号等特性。MysQL提供了一种转义机制,称为MysQL真实转义字符串(),它将反斜杠加到一些特殊字符前,包括\\x00, \\n, \\r, , ’, "和\\x1A。请使目此函数修复前面任务中识别的SQL注入漏洞。在执行此任务之前,应禁用前面任务中描述的其他保护方案。
mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。
下列字符受影响:
\\x00、\\n、\\r、\\、’、"、\\x1a
如果成功,则该函数返回被转义的字符串。如果失败,则返回 false。
// 转义用户名和密码,以便在 SQL 中使用
u
s
e
r
=
m
y
s
q
l
r
e
a
l
e
s
c
a
p
e
s
t
r
i
n
g
(
user = mysql_real_escape_string(
user=mysqlrealescapestring(user);
p
w
d
=
m
y
s
q
l
r
e
a
l
e
s
c
a
p
e
s
t
r
i
n
g
(
pwd = mysql_real_escape_string(
pwd=mysqlrealescapestring(pwd);
任务3.3.4
·任务3.4:准备声明。将数据与SQL逻辑分离的一个更通用的解决方案是准确地告诉数据库哪个部分是数据部分,哪个部分是逻辑部分。MySQL为此提供了prepare 语句机制。
$db = new mysqli(“localhost”, “user”, “pass”, “db”);
$stmt = $db->prepare(“SELECT * FROM users WHERE name=? AND age=?”);
$stmt->bind_param(“si”, $user, $age);
s
t
m
t
−
>
e
x
e
c
u
t
e
(
)
;
使
用
p
r
e
p
a
r
e
语
句
机
制
,
我
们
将
向
数
据
库
发
送
S
Q
L
语
句
的
过
程
分
为
两
个
步
骤
。
第
一
步
是
发
送
代
码
,
即
,
没
有
需
要
稍
后
插
入
的
数
据
的
S
Q
L
语
句
。
这
是
准
备
步
骤
。
在
此
步
骤
之
后
,
我
们
将
使
用
b
i
n
d
p
a
r
a
m
(
)
将
数
据
发
送
到
数
据
库
。
数
据
库
将
只
将
在
此
步
骤
中
发
送
的
所
有
内
容
视
为
数
据
,
而
不
再
将
其
视
为
代
码
。
请
使
用
p
r
e
p
a
r
e
语
句
机
制
修
复
p
h
p
B
B
2
代
码
中
的
S
Q
L
注
入
漏
洞
。
在
b
i
n
d
p
a
r
a
m
函
数
中
,
第
一
个
参
数
“
s
i
”
表
示
第
一
个
参
数
(
stmt->execute(); 使用prepare语句机制,我们将向数据库发送SQL语 句的过程分为两个步骤。第一步是发送代码,即,没有需要稍后插入的数据的SQL语句。这是准备步骤。在此步骤之 后,我们将使用bind_param()将数据发送到数据库。数据库将只将在此步骤中发送的所有内容视为数据,而不再将其视为代码。 请使用prepare语句机制修复phpBB2代码中的SQL注入漏洞。在 bind_param 函数中,第一个参数“si”表示第一个参数(
stmt−>execute();使用prepare语句机制,我们将向数据库发送SQL语句的过程分为两个步骤。第一步是发送代码,即,没有需要稍后插入的数据的SQL语句。这是准备步骤。在此步骤之后,我们将使用bindparam()将数据发送到数据库。数据库将只将在此步骤中发送的所有内容视为数据,而不再将其视为代码。请使用prepare语句机制修复phpBB2代码中的SQL注入漏洞。在bindparam函数中,第一个参数“si”表示第一个参数(user)是字符串类型,第二个参数(Sage)是整数类型。
以上是关于软件安全实验——lab8(SQL注入)(上)(旧虚拟机seedubuntu9版本实验)的主要内容,如果未能解决你的问题,请参考以下文章