php特性函数(正则\漏洞函数)

[MRCTF2020]套娃

打开界面发现源码,

第一关

$query = $_SERVER['QUERY_STRING'];的意思就是返回?后的值
第一个if是检查,有没有下划线  %5f下划线的编码 所以我们要达到的效果就是?传参没有_下划线

 利用PHP的字符串解析特性Bypass - FreeBuf网络安全行业门户

空格、+ - [ .  都可以换成_,我们这里用空格代替

 第二个if是强比较不等于2333,后面正则2开头3结束格式,这样我们就只能在%0a进行换行绕过

 第二关

 看见源码注释掉了,看了大佬的wp,说这是JsFuck加密,我还真没听说过

把他复制到控制器,运行

获得提示,让我们传参Merak,随便传入一个值 比如Merak=sfsf 

第三关

Flag is here~But how to get it? <?php 
error_reporting(0); 
include 'takeip.php';
ini_set('open_basedir','.'); 
include 'flag.php';

if(isset($_POST['Merak'])){ 
    highlight_file(__FILE__); 
    die(); 
} 


function change($v){ 
    $v = base64_decode($v); 
    $re = ''; 
    for($i=0;$i<strlen($v);$i++){ 
        $re .= chr ( ord ($v[$i]) + $i*2 ); 
    } 
    return $re; 
}
echo 'Local access only!'."<br/>";
$ip = getIp();
if($ip!='127.0.0.1')
echo "Sorry,you don't have permission!  Your ip is :".$ip;
if($ip === '127.0.0.1' && file_get_contents($_GET['2333']) === 'todat is a happy day' ){
echo "Your REQUEST is:".change($_GET['file']);
echo file_get_contents(change($_GET['file'])); }
?>  

首先第一个if是判断 是否是本地ip地址

然后file_get_contents($_GET['2333']) === 'todat is a happy day'  data读取

 可是到这里ip已经用插件设置了127.0.0.1,没通过,百度一下

CLIENT-IP: 127.0.0.1  这里x-forwarded-for失效了

成功,最后看change的作用, $v = base64_decode($v)里面是base64解码,所以我们传参需要先编码,也就是flag.php  每个字符加 i*2

所以我们先减在传入

c='flag.php'
for num in range(0,8):
    a = chr(int(ord(c[num])) - num * 2)
    print(str(a),end="")

得到,fj]a&f\b直接base64编码传入就可以了

[Zer0pts2020]Can you guess it?

<?php
include 'config.php'; // FLAG is defined in config.php

if (preg_match('/config\.php\/*$/i', $_SERVER['PHP_SELF'])) {
  exit("I don't know what you are thinking, but I won't let you read it :)");
}

if (isset($_GET['source'])) {
  highlight_file(basename($_SERVER['PHP_SELF']));
  exit();
}

$secret = bin2hex(random_bytes(64));
if (isset($_POST['guess'])) {
  $guess = (string) $_POST['guess'];
  if (hash_equals($secret, $guess)) {
    $message = 'Congratulations! The flag is: ' . FLAG;
  } else {
    $message = 'Wrong.';
  }
}
?>

$_SERVER['PHP_SELF']是当前执行的脚本名,比如url是:http://xxx/index.php     $SERVER['PHP_SELF']的值就是index.php

如果url是:http://xxx/index.php/a.php/a/b/c/d/?a=1   $_SERVER['PHP_SELF']的值就是index.php/a.php/a/b/c/d/  (忽略传参)

hash_equals($secret, $guess)是判断两个参数是否相等

bin2hex  字符串转为十六进制

该函数以字符串形式返回加密安全的随机字节  random_bytes

本来觉得突破口是两个参数相等,然后得到flag,可是是随机生成的,那看看别的点 

源码里有一句:

highlight_file(basename($_SERVER['PHP_SELF']));

如果url是:http://xxx/index.php/a      basename($_SERVER['PHP_SELF'])的值就是a  (只看最后一个/后面的,同样忽略传参)

正则:/config\.php\/*$/i  最后是个*,传一个中文字符(打印不出来),正则就会失效

题目给出了flag在config.php,我们要得到这个php,如果访问index.php/config.php,其实依然是index.php的界面

 这道题给出了basename()的漏洞,只看最后一个/的后面,而且忽略上传参数

比如$path是/var/www/html/index.php,那么basename($path);得到的就是index.php。

<?php
function check($str){
    return preg_match('/config\.php\/*$/i', $str);
}

for($i=0;$i<255;$i++){
    $str="/index.php/config.php/".chr($i);
    if(!check($str)){
        echo $i.":".basename($str);
        echo "<br>";
    }
}

ASCII值范围为0-255,但ASCII码并没有规定编号为128~255的字符,ASCII表范围为0-127,也就是我们传入128以上的数值,即可绕过正则,128 -> 0x80

 这样既可以访问config.php,也可以绕过正则

还有几个中文符号也可以比如:?中文汉字都可以,打印不出来

[GWCTF 2019]枯燥的抽奖

打开界面

一看见想的本来是爆破,然后想了一下,不行呀这样得爆破到猴年马月,也不是有一部分对就是回显别的汉字。看一下源码

看见了个地址, 

 访问得到,源码

jgBHnUZqTT

<?php
#这不是抽奖程序的源代码!不许看!
header("Content-Type: text/html;charset=utf-8");
session_start();
if(!isset($_SESSION['seed'])){
$_SESSION['seed']=rand(0,999999999);
}

mt_srand($_SESSION['seed']);   这是赋予的一个seed种子
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str='';
$len1=20;
for ( $i = 0; $i < $len1; $i++ ){
    $str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);       
}
$str_show = substr($str, 0, 10);
echo "<p id='p1'>".$str_show."</p>";


if(isset($_POST['num'])){
    if($_POST['num']===$str){x
        echo "<p id=flag>抽奖,就是那么枯燥且无味,给你flag{xxxxxxxxx}</p>";
    }
    else{
        echo "<p id=flag>没抽中哦,再试试吧</p>";
    }
}
show_source("check.php");

    $str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);       
表面,这是一个随机0-strlen的随机,可是mt_rand通过一种复杂的运算存在规律

我们可以通过第一个值,也就是给出的jgBHnUZqTT通过一定的运算可以推算出下面的值,拼接形成flag

知识点:PHP mt_rand安全杂谈及应用场景详解 - FreeBuf网络安全行业门户

首先,第一步我们先将给出的第一段字符换成数字

str1="jgBHnUZqTT"
str2= "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
length=str(len(str2)-1)
result=''
for i in range(0,len(str1)):
    for j in range(0,len(str2)):
        if str2[j]==str1[i]:
            result+=str(j)+' '+str(j)+' '+'0'+' '+length+' '
print(result)

 

9 9 0 61 6 6 0 61 37 37 0 61 43 43 0 61 13 13 0 61 56 56 0 61 61 61 0 61 16 16 0 61 55 55 0 61 55 55 0 61  

以上面生成的随机数为例,假设我们知道了第一个生成的随机数,那我们怎么预测种子呢?
那就要用到php_mt_seed这个工具了。

得到的seed为209641505 ,根据seed去得到密文就行了,要用php7.1及以上版本的

<?php
mt_srand(209641505);

$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str='';
$len1=20;
for ( $i = 0; $i < $len1; $i++ ){
    $str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);       
}
echo $str;
?>

 

然后php这段代码,需要用php7.1+的版本,否则的出来的不太一样,因为seed提示了php版本,输入得到flag

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值