第一次php代码审计

1.源代码

 <?php

require_once('flag.php');
error_reporting(0);


if(!isset($_GET['msg'])){
    highlight_file(__FILE__);
    die();
}

@$msg = $_GET['msg'];
if(@file_get_contents($msg)!=="Hello Challenge!"){//php://input绕过
    die('Wow so rude!!!!1');
}

echo "Hello Hacker! Have a look around.\n";

@$k1=$_GET['key1'];
@$k2=$_GET['key2'];

$cc = 1337;$bb = 42;

if(intval($k1) !== $cc || $k1 === $cc){//GET类型接收的参数值类型为字符串,所以1337直接绕过
    die("lol no\n");
}

if(strlen($k2) == $bb){
    if(preg_match('/^\d+$/', $k2) && !is_numeric($k2)){//这里比较坑,$符并不表示匹配输入行尾位置,可以用url编码测试一下
        if($k2 == $cc){
            @$cc = $_GET['cc'];
        }
    }
}

list($k1,$k2) = [$k2, $k1];

if(substr($cc, $bb) === sha1($cc)){//利用substr和sha1返回FALSE绕过
    foreach ($_GET as $lel => $hack){
        $$lel = $hack;//对k1变量覆盖
    }
}

$‮b = "2";$a="b";//;1=b
//上面一行代码是$b="2";$a="b";//$b=1
if($$a !== $k1){//经过上面$$a值为2,所以我们可以为k1变量覆改为2
    die("lel no\n");
}

// plz die now
assert_options(ASSERT_BAIL, 1);
assert("$bb == $cc");//assert()将字符串参数当做php代码执行

echo "Good Job ;)";
// TODO
// echo $flag;   
?>

1.)首先利用php://input伪协议绕过(@file_get_contents($msg)!=="Hello Challenge!")

1.1)file_get_concents() 函数把整个文件读入一个字符串中

语法 : file_get_contents(path,include_path,context,start,max_length)

参数描述
path必需。规定要读取的文件。
include_path可选。如果也想在 include_path 中搜寻文件的话,可以将该参数设为 "1"。
context

可选。规定文件句柄的环境。

context 是一套可以修改流的行为的选项。若使用 null,则忽略。

start可选。规定在文件中开始读取的位置。该参数是 PHP 5.1 新加的。
max_length可选。规定读取的字节数。该参数是 PHP 5.1 新加的
例子
<?php echo file_get_contents("test.txt"); ?>
输出:This is a test file with test text.

1.2)php://input

当对file_get_contents传进去的参数作为文件名变量去打开文件时,可以将参数php://传进,同时post方式传进去值作为文件内容,供php代码执行时当做文件内容读取

2.)intval和===

2.1)intval函数获取变量整数数值
Intval 最大的值取决于操作系统。 32 位系统最大带符号的 integer 范围是 -2147483648 到 2147483647。举例,在这样的系统上, intval(‘1000000000000’) 会返回 2147483647。64 位系统上,最大带符号的 integer 值是 9223372036854775807。这个有个应用就是在判断数值是不是回文上,如果参数为2147483647,那么当它反过来,由于超出了限制,所以依然等2147483647。即为回文。当然这里用不上

intval — 获取变量的整数值

int intval ( mixed $var [, int $base = 10 ] )

通过使用指定的进制 base 转换(默认是十进制),返回变量 var 的 integer 数值。 intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1。

var

要转换成 integer 的数量值

base

转化所使用的进制

Note:

如果 base 是 0,通过检测 var 的格式来决定使用的进制:

  • 如果字符串包括了 "0x" (或 "0X") 的前缀,使用 16 进制 (hex);否则,
  • 如果字符串以 "0" 开始,使用 8 进制(octal);否则,
  • 将使用 10 进制 (decimal)。

成功时返回 var 的 integer 值,失败时返回 0。 空的 array 返回 0,非空的 array 返回 1。

最大的值取决于操作系统。 32 位系统最大带符号的 integer 范围是 -2147483648 到 2147483647。举例,在这样的系统上, intval('1000000000000') 会返回 2147483647。64 位系统上,最大带符号的 integer 值是 9223372036854775807。

字符串有可能返回 0,虽然取决于字符串最左侧的字符。 使用 整型转换 的共同规则。

2.2)

===是恒等计算符   同时检查表达式的值与类型

==是比较运算符号  不会检查条件式的表达式的类型(弱类型,类型自动转换)

这里因为从$_GET接收的参数类型都是String(本地可以测试一下),所以输入1337可以直接绕过

3.)因为代码中的$不表示匹配输入行尾,所以这里可以进行正则匹配绕过。

其次is_numeric()  判断变量是否为数字或数字字符串,不仅检查10进制,16进制是可以。

is_numeric函数对于空字符%00,无论是%00放在前后都可以判断为非数值,而%20空格字符只能放在数值后。所以,查看函数发现该函数对对于第一个空格字符会跳过空格字符判断,接着后面的判断!该函数还可能造成sql注入,例如将‘1 or 1'转换为16进制形式,再传参,就可以造成sql注入。

当然此处用不到,因为可以构造key2=1337$aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa进行绕过

4.)利用substr和sha1函数同时返回FALSE绕过

4.1)

substr — 返回字符串的子串

string substr ( string $string , int $start [, int $length ] )

返回字符串 stringstartlength 参数指定的子字符串。

string

输入字符串。必须至少有一个字符。

start

如果 start 是非负数,返回的字符串将从 stringstart 位置开始,从 0 开始计算。例如,在字符串 "abcdef" 中,在位置 0 的字符是 "a",位置 2 的字符串是 "c" 等等。

如果 start 是负数,返回的字符串将从 string 结尾处向前数第 start 个字符开始。

如果 string 的长度小于 start,将返回 FALSE。(这里用到的是这个)

length

如果提供了正数的 length,返回的字符串将从 start 处开始最多包括 length 个字符(取决于 string 的长度)。

如果提供了负数的 length,那么 string 末尾处的 length 个字符将会被省略(若 start 是负数则从字符串尾部算起)。如果 start 不在这段文本中,那么将返回 FALSE

如果提供了值为 0FALSENULLlength,那么将返回一个空字符串。

如果没有提供 length,返回的子字符串将从 start 位置开始直到字符串结尾。

4.2)sha1()函数无法处理数组类型,将报错并返回FALSE。经验证md5()函数同样存在此漏洞。

5.下面就是变量覆盖了

由代码$b="2";$a="b";可以知道$$a的值为2,所以我们可以为k1变量覆改为2,以此绕过$$a !== $k1

6.在下面就是命令执行了(利用assert函数)

将b利用变量覆盖为system("vim ./flag.php");//就可以访问flag.php文件了,即可发现flag

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值