PHP代码审计分段讲解(8)
20 十六进制与数字比较
源代码为:
<?php error_reporting(0);
function noother_says_correct($temp)
{
$flag = 'flag{test}';
$one = ord('1'); //ord — 返回字符的 ASCII 码值
$nine = ord('9'); //ord — 返回字符的 ASCII 码值
$number = '3735929054';
// Check all the input characters!
for ($i = 0; $i < strlen($number); $i++)
{
// Disallow all the digits!
$digit = ord($temp{$i});
if ( ($digit >= $one) && ($digit <= $nine) )
{
// Aha, digit not allowed!
return "flase";
}
}
if($number == $temp)
return $flag;
}
$temp = $_GET['password'];
echo noother_says_correct($temp); ?>
GET方式传入password的值,输出经过noother_says_correct函数处理之后的值。
noother_says_correct函数处理的逻辑为:先对password中的每一位进行判断,若在1--9之间,则直接返回false,若都满足,并且$number = '3735929054',$number==$password,则返回flag。
我们很容易能够注意到:
$number == $temp
这里两个等号,是弱类型比较,即会先将比较的两者类型进行转化后再比较,在计算机中0x开头的表示为十六进制,所以我们可以使用十六进制来绕过前面的for循环,同时满足等于temp
3735929054转换成十六进制后为:deadc0de
加上0x后为0xdeadc0de,可以看出可以逃逸出for循环中的限制,所以最后的payload为:
?password=0xdeadc0de
21 数字验证正则绕过
<?php error_reporting(0);
$flag = 'flag{test}';
if ("POST" == $_SERVER['REQUEST_METHOD'])
{
$password = $_POST['password'];
if (0 >= preg_match('/^[[:graph:]]{12,}$/', $password)) //preg_match — 执行一个正则表达式匹配
{
echo 'Wrong Format';
exit;
}
while (TRUE)
{
$reg = '/([[:punct:]]+|[[:digit:]]+|[[:upper:]]+|[[:lower:]]+)/';
if (6 > preg_match_all($reg, $password, $arr))
break;
$c = 0;
$ps = array('punct', 'digit', 'upper', 'lower'); //[[:punct:]] 任何标点符号 [[:digit:]] 任何数字 [[:upper:]] 任何大写字母 [[:lower:]] 任何小写字母
foreach ($ps as $pt)
{
if (preg_match("/[[:$pt:]]+/", $password))
$c += 1;
}
if ($c < 3) break;
//>=3,必须包含四种类型三种与三种以上
if ("42" == $password) echo $flag;
else echo 'Wrong password';
exit;
}
} ?>
这里用到了PHP正则表达式,简单列举一下字符串类的正则表达式:
[[:alpha:]] :匹配任何字母
[[:digit:]] :匹配任何数字
[[:alnum:]] :匹配任何字母和数字
[[:space:]] :匹配任何空白字符
[[:upper:]] :匹配任何大写字母
[[:lower:]] :匹配任何小写字母
[[:punct:]] :匹配任何标点符号
[[:xdigit:]] :匹配任何16进制数字,相当于[0-9a-fA-F]
[[:blank:]] :匹配空格和Tab,等价于[\t]
[[:cntrl:]] :匹配所有ASCII 0到31之间的控制符
[[:graph:]] :匹配所有的可打印字符,等价于[^ \t\n\r\f\v]
[[:print:]] :匹配所有的可打印字符和空格,等价于[^\t\n\r\f\v]
使用POST方式传输password
if ("POST" == $_SERVER['REQUEST_METHOD'])
{
$password = $_POST['password'];
第一个if中正则表达式匹配所有的可打印字符,并且需要大于等于12个
if (0 >= preg_match('/^[[:graph:]]{12,}$/', $password)) //preg_match — 执行一个正则表达式匹配
{
echo 'Wrong Format';
exit;
}
然后是一个while循环
第二个 if 里面,使用 preg_match_all
$reg = '/([[:punct:]]+|[[:digit:]]+|[[:upper:]]+|[[:lower:]]+)/';
按照这个规则(标点符号;数字;大写字母;小写字母),将password至少分为6段
例如:abc123+a1? 就可以分为:abc 123 + a 1 ? 这6段
第三个 if 中,使用 for 循环判断 password 中是否存在 标点符号,数字,大写字母,小写字母中的至少三种
$c = 0;
$ps = array('punct', 'digit', 'upper', 'lower'); //[[:punct:]] 任何标点符号 [[:digit:]] 任何数字 [[:upper:]] 任何大写字母 [[:lower:]] 任何小写字母
foreach ($ps as $pt)
{
if (preg_match("/[[:$pt:]]+/", $password))
$c += 1;
}
if ($c < 3) break;
最后想要获得 flag ,还需要令传入的password=="42"
if ("42" == $password) echo $flag;
从最后的相等出发,因为是弱类型比较,我们首先想到的是十六进制或者科学计数法。
在科学计数法中,有:https://www.php.net/manual/en/language.operators.comparison.php
其中
var_dump(0 == "a"); // 0 == 0 -> true
var_dump("1" == "01"); // 1 == 1 -> true
var_dump("10" == "1e1"); // 10 == 10 -> true
var_dump(100 == "1e2"); // 100 == 100 -> true
所以我们可以有 4.2e1==42,也可以有420e-1==42,当然还可以继续如0.42e2==42
为了多一个减号,我们采用420e-1,再变形为:420.0e-1,满足password分成六段的要求,接着满足长度大于等于12的要求,变形为:420.00000e-1
POST传输:
参考链接:
http://bayescafe.com/php/yuebaomei-ctf.html
PHP代码审计分段讲解(8)的更多相关文章
- PHP代码审计分段讲解(14)
30题利用提交数组绕过逻辑 本篇博客是PHP代码审计分段讲解系列题解的最后一篇,对于我这个懒癌患者来说,很多事情知易行难,坚持下去,继续学习和提高自己. 源码如下: <?php $role = ...
- PHP代码审计分段讲解(13)
代码审计分段讲解之29题,代码如下: <?php require("config.php"); $table = $_GET['table']?$_GET['table']: ...
- PHP代码审计分段讲解(11)
后面的题目相对于之前的题目难度稍微提升了一些,所以对每道题进行单独的分析 27题 <?php if(!$_GET['id']) { header('Location: index.php?id= ...
- PHP代码审计分段讲解(1)
PHP源码来自:https://github.com/bowu678/php_bugs 快乐的暑期学习生活+1 01 extract变量覆盖 <?php $flag='xxx'; extract ...
- PHP代码审计分段讲解(12)
28题 <!DOCTYPE html> <html> <head> <title>Web 350</title> <style typ ...
- PHP代码审计分段讲解(10)
26 unserialize()序列化 <!-- 题目:http://web.jarvisoj.com:32768 --> <!-- index.php --> <?ph ...
- PHP代码审计分段讲解(9)
22 弱类型整数大小比较绕过 <?php error_reporting(0); $flag = "flag{test}"; $temp = $_GET['password' ...
- PHP代码审计分段讲解(7)
17 密码md5比较绕过 <?php if($_POST[user] && $_POST[pass]) { mysql_connect(SAE_MYSQL_HOST_M . ': ...
- PHP代码审计分段讲解(6)
14 intval函数四舍五入 <?php if($_GET[id]) { mysql_connect(SAE_MYSQL_HOST_M . ':' . SAE_MYSQL_PORT,SAE_M ...
随机推荐
- layui table表格详解
上次做table有些东西 忘记了 这次当作来个分析总结一下 跟大家共同学习 闲话不多说 直接上例子 代码: <form id="form1" runat="s ...
- php xml转数组
<?php libxml_disable_entity_loader(true); $notify_values = json_decode(json_encode(simplexml_load ...
- 守护进程详解以及start-stop-daemon命令
1.概念:守护进程是在后台运行的不受终端控制的进程,通常守护进程在系统启动时自动运行,守护进程的名称通常以d结尾,比如sshd.xinetd.crond等. 2.创建守护进程的步骤:a.调用fork( ...
- 利用matlibplot绘制雷达图
之前在一些数据分析案例中看到用 Go 语言绘制的雷达图,非常的漂亮,就想着用matlibplot.pyplot也照着画一个,遗憾的是matlibplot.pyplot模块中没有直接绘制雷达图的函数,不 ...
- spring 2.5 基础知识和与其他框架的集成
spring环境搭建: 一:导入spring2.5所需的包,在classpath目录下建一个名为"beans.xml"模板文件: <?xml version="1. ...
- K8S环境的Jenkin性能问题描述
Return Homezq2599 CnBlogsHomeContactAdminPosts - 75 Articles - 0 Comments - 16 K8S环境的Jenkin性能问题处理 环境 ...
- mysql主备切换canal出现的问题解析
通过配置VIP,在进行主备切换时,出现的报错信息: 1.当主备节点当前binlog文件名称相同时,原主节点的position小于主备切换后的position,出现如下报错: 2020-07-02 15 ...
- 精尽MyBatis源码分析 - MyBatis初始化(四)之 SQL 初始化(下)
该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...
- C#设计模式-外观模式(Facade Pattern)
引言 在软件测试中,一般都是在功能测试稳定的情况下再进行UI自动化测试.或者进行性能测试.如果一个一个进行太麻烦,此时可以使用对外提供一个简单接口,通过这个接口可以访问内部一群接口.例如进行UI自动化 ...
- 如何用pdfFactory新建打印机并设置属性
今天我们来讲一讲,在pdfFactory中如何去修改PDF文件打印页面的页边距.页面大小.页面清晰度等属性参数. pdfFactory是一款Windows平台上的虚拟打印机,在没有打印机可以安装的情况 ...