【?】Web_BUUCTF_WriteUp | [GXYCTF2019]Ping Ping Ping

发布时间 2023-12-03 10:44:16作者: Guanz

题目

分析

ping 一个任意 ip:


拼一个命令试试:


看来是命令执行漏洞,直接查看 flag.php,发现存在空格过滤:


尝试绕过空格过滤:

还有 { } 符号过滤。


过滤了 flag 关键字,尝试绕过:

过滤了单双引号。


\ 符号、\$+数字、\$+@ 没有用。


变量拼接没有输出。


看看 index.php:

<?php
if(isset($_GET['ip'])){
  $ip = $_GET['ip'];
  if(preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{1f}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){
    // 执行正则表达式,在变量ip中匹配到&、/、?、*、<、ASCII表前32个控制字符、>、'、"、\、(、)、[、]、{、}赋给变量match。若匹配到则输出1,否则输出0
    echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match);
    // 输出fxck your symbol!并退出当前脚本
    die("fxck your symbol!");
    // 否则若匹配到空格
  } else if(preg_match("/ /", $ip)){
    // 输出fxck your space!并退出当前脚本
    die("fxck your space!");
    // 否则若匹配到bash
  } else if(preg_match("/bash/", $ip)){
    // 输出fxck your bash!并退出当前脚本
    die("fxck your bash!");
    // 否则若依次匹配到f、l、a、g
  } else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
    // 输出fxck your flag!并退出当前脚本
    die("fxck your flag!");
  }
  // 执行命令ping -c 4 拼接变量ip,输出作为字符串给变量a
  $a = shell_exec("ping -c 4 ".$ip);
  // 输出两个空行
  echo "

";
  // 输出变量a
  print_r($a);
}

?>

也就是说,如果依次匹配到 f l a g 四个字符也会退出脚本,理论上变量拼接是满足要求的。


查找资料发现 $ 符号后的部分会被当成一个变量,除非读取到下一个 $ 符号;由于 shell 变量不能以数字开头,所以 $ +数字的组合表示向脚本传递某个位置参数;同时,shell 变量的命名规则中不包含 .
也就是说变量需要从后往前拼接,如:


当然,flag 全作为变量拼接的情况除外:


此外,用反引号 `(英文语言键盘主键区左上角)内敛绕过也是可以的:


也可以使用 Base64 绕过:

Flag

flag{c049a763-0991-4f71-92b6-e93023fd894d}

总结

  1. 绕过空格的方法:Linux下绕过空格的方式总结-解忧杂货铺o_O-CSDN
  2. 绕过关键字的方法:Linux系统下绕过某个关键字的小技巧,比如flag关键字-若丶时光破灭-CSDN
  3. 替代空格的部分为 $IFS$9,否则 IFS 可能无法被识别为内部域分隔符
  4. 【?】通过 ; 拼接的命令输出没有直接显示。猜测是因为 ip 没有被赋值,; 之后命令的输出与变量 a 无关而不被输出。

参考

Linux下绕过空格的方式总结-解忧杂货铺o_O-CSDN
Linux系统下绕过某个关键字的小技巧,比如flag关键字-若丶时光破灭-CSDN
PHP preg_match() 函数-菜鸟教程
正则表达式 – 教程-菜鸟教程
PHP_ shell_exec-Manual
shell命令之 IFS详解-笑洋仟-博客园
命令执行绕过的方法-阜城小柳-博客园
Shell 元字符—Linux latest 文档
shell 变量赋值的详细使用-Fe_cow丿-CSDN
$加数字在Shell中的含义-阿东-腾讯云开发者社区
Linux中的管道与连接符号-Curren.wong-CSDN