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