系统安全实验(php代码审计,审计过滤)

1.php代码审计
https://blog.csdn.net/wu_tongtong/article/details/123766106

是真的会sleep这么久,所以不考虑考虑其他输入时间的姿势嘛?强制转换和is_numeric()相比有哪些不足呢?

关于PHP基本概念和PHP代码审计https://blog.csdn.net/weixin_54977781/article/details/123600895
PHP 是可以创建动态交互性站点的强有力的服务器端的脚本语言。
PHP可以做很多东西,特别是web网站开发,也可以使用的非常广泛。能够快速,灵活,实用使得PHP语言可以更好的开发任何网站。
PHP 是一种 HTML 嵌入式的脚本语言。php文件以.php结尾。PHP语言的很多语法来自 C,Java 和 Perl,并具有几个 PHP 独有的特点。PHP语言的主要目标是让 Web 开发程序员可以快速的书写动态生成的网页。

先浏览器访问靶机ip 看到php代码
在这里插入图片描述
在php语言中,hr的意思为 " 水平线 ",是一个定义水平线分隔的html标签,其表现形式为一条横线,视觉上可以将文档分隔成两个部分
输出hr的语法 echo'<hr>' 打了个<hr>出现了下面这条线哈哈


show_source函数通过使用 php 语法高亮程序中定义的颜色,输出或返回包含在 filename 中的代码的语法高亮版本

isset()函数是判断变量是否存在,存在返回值1,不存在返回值空.
is_numeric()函数 是判断变量是否是数字或者数字字符串.

输入一个变量: src=“example.php?id=5”
提交两个或多个变量,变量之间加&
src=“example.php?id=5&page=5&color=red”

在这里插入图片描述
在这里插入图片描述
选个合法时间
在这里插入图片描述
很怪,7e6或者6.48e6就是如上图 跑不出来 写6480000就一直加载
!因为sleep函数进行延时!第一个条件是我们自己传入的,sleep延时时间太久,我们不可能等他那么久。只需要绕过sleep就可以得到flag
绕过sleep:
is_numeric()支持普通数字型字符串、科学记数法型字符串、部分支持十六进制0x型字符串。而强制类型转换int,不能正确转换的类型有十六进制型字符串、科学计数法型字符串(部分)。

也就是说,当传入?time=7e6,由于int无法转科学计数法,会把它当做7处理,这样首先7e6满足 5184000<time<7776000 ,然后进入sleep延迟,在int不能转换科学计数法的条件下,延迟七秒得到flag。
include 函数包含并运行指定文件。
我们需要还提供一个正确的路径(存放flag的文件路径)
学姐尝试了flag.txt,flag.php,./flag但是没有找到 后面的看不懂了 大概是按经验flag在根目录下 所以有
在这里插入图片描述

2.审计过滤

题目描述
浏览器进入靶机IP地址首页,并借助靶机IP/Source.txt所提供的首页源码,尝试构造合适的number过滤掉所有的限制条件,找到flag!

访问靶机ip/Source.txt 看到以下内容 (https://www.cnblogs.com/murkuo/p/14970535.html加注释版)

<?php
 
$info = ""; 
$req = [];
$flag="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
 
ini_set("display_error", false); //为一个配置选项设置值
error_reporting(0); //关闭所有PHP错误报告
 
if(!isset($_GET['number'])){
   header("hint:26966dc52e85af40f59b4fe73d8c323a.txt"); //HTTP头显示hint 26966dc52e85af40f59b4fe73d8c323a.txt
 
   die("have a fun!!"); //die — 等同于 exit()
 
}
 
foreach([$_GET, $_POST] as $global_var) {  //foreach 语法结构提供了遍历数组的简单方式 
    foreach($global_var as $key => $value) { 
        $value = trim($value);  //trim — 去除字符串首尾处的空白字符(或者其他字符)
        is_string($value) && $req[$key] = addslashes($value); // is_string — 检测变量是否是字符串,addslashes — 使用反斜线引用字符串
    } 
} 
 
 
function is_palindrome_number($number) { 
    $number = strval($number); //strval — 获取变量的字符串值
    $i = 0; 
    $j = strlen($number) - 1; //strlen — 获取字符串长度
    while($i < $j) { 
        if($number[$i] !== $number[$j]) { 
            return false; 
        } 
        $i++; 
        $j--; 
    } 
    return true; 
} 
 
 
if(is_numeric($_REQUEST['number'])) //is_numeric — 检测变量是否为数字或数字字符串 
{
 
   $info="sorry, you cann't input a number!";
 
}
elseif($req['number']!=strval(intval($req['number']))) //intval — 获取变量的整数值
{
 
     $info = "number must be equal to it's integer!! ";  
 
}
else
{
 
     $value1 = intval($req["number"]);
     $value2 = intval(strrev($req["number"]));  
 
     if($value1!=$value2){
          $info="no, this is not a palindrome number!";
     }
     else
     {
 
          if(is_palindrome_number($req["number"])){
              $info = "nice! {$value1} is a palindrome number!"; 
          }
          else
          {
             $info=$flag;
          }
     }
 
}

截断类型:PHP%00截断。
截断原理:由于00表示结束符,所以会把00后面的所有字符删除。
截断条件:PHP版本<5.3.4,q且PHP的magic_quotes_gpc为OFF状态。
绕过方法:服务端将GET参数jieduan的内容作为上传后文件名的第一部分,然后将按时间生成的文件名作为第二部分。例如修改参数jieduan为1.php%00.JPG,文件保存到服务器时,%00会把.jpg和按时间生成的图片文件名全部截断,那么文件名就只剩下1.php。
这段代码实现了一个回文数检查程序,通过输入一个字符串或数字,判断其是否是回文数。如果输入的不是回文数,则程序会返回相应提示;如果是回文数,则返回一个 flag。

程序会从 GET 或 POST 请求中获取输入参数,并将其值存储在 $req 数组中。is_palindrome_number() 函数用来判断一个数是否是回文数。该函数首先将输入参数转换成字符串类型,并从字符串的两端开始逐个比较字符,如果字符串两端的字符相同,就继续比较下一组字符,如果都相同,则该字符串是回文字符串。

接着程序会对输入参数进行校验,首先判断输入参数是否为数值类型,如果是,则返回 “sorry, you cann’t input a number!” 提示。如果不是,则判断输入参数是否是整数类型,如果不是,则返回 "number must be equal to it’s integer!! " 提示。如果是整数类型,则使用 intval() 函数将其转换成整数,并使用 strrev() 函数将其反转,然后再次使用 intval() 函数将其转换成整数,最后判断这两个整数是否相等,如果不相等,则说明输入不是回文数,返回 “no, this is not a palindrome number!” 提示。如果两个整数相等,则再次调用 is_palindrome_number() 函数来判断输入是否是回文数,如果是,则返回 “nice! {$value1} is a palindrome number!” 提示,否则返回 $flag 变量的值,即 flag。

题解:

限制条件解读:
为了找到 flag,你需要绕过所有的限制条件。这个代码对输入参数做了多层过滤,因此需要仔细分析每一层的限制条件,才能找到绕过它们的方法。

首先,代码判断输入参数是否为数字类型,如果是,则返回 “sorry, you cann’t input a number!” 提示。但是,它只判断了是否为数字类型,并没有判断是否为科学计数法,因此,你可以通过构造一个科学计数法的输入,绕过这个限制条件。例如,可以构造一个输入参数 number=7e5,它将会被解析为科学计数法的表示方式,绕过了代码中的数字类型判断。
其次,代码判断输入参数是否为整数类型,如果不是,则返回 "number must be equal to it’s integer!! " 提示。但是,这里的判断有一个漏洞,因为代码只判断了字符串是否等于其整数值,没有判断其浮点值是否等于整数值。因此,你可以通过构造一个带有浮点数值的输入参数,例如 number=1.0,绕过这个限制条件。
最后,代码通过将输入参数反转,判断其是否为回文数。但是,它没有判断输入参数是否为字符串类型,因此你可以通过构造一个数组作为输入参数,例如 number[]=12345,绕过这个限制条件。

strval会忽略掉%00和%20
is_numeric函数可以使用%00作为开头绕过
is_numeric函数在开始判断前,会先跳过空白字符和部分其他字符,包括\r,\n,\t,\f,space等等
intval函数在开始判断前,会先跳过空白字符和部分其他字符,包括\r,\n,\t,\f,space等等
is_numeric函数支持普通数字型字符串、科学记数法型字符串、部分支持十六进制0x型字符串
强制类型转换int,不能正确转换的类型有十六进制型字符串、科学计数法型字符串(部分)
即(int)7e6会被认为是7

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值